Selaa lähdekoodia

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

Pamela Wolf 5 vuotta sitten
vanhempi
commit
d2baae8907
100 muutettua tiedostoa jossa 5695 lisäystä ja 1654 poistoa
  1. 2 2
      Viewer/src/managers/sceneManager.ts
  2. 0 1
      Viewer/src/managers/telemetryManager.ts
  3. 0 2
      Viewer/src/templating/templateManager.ts
  4. 0 2
      Viewer/src/viewer/viewerManager.ts
  5. 1 1
      Viewer/tests/commons/helper.ts
  6. 51 31
      dist/preview release/babylon.d.ts
  7. 2 2
      dist/preview release/babylon.js
  8. 2593 214
      dist/preview release/babylon.max.js
  9. 1 1
      dist/preview release/babylon.max.js.map
  10. 103 62
      dist/preview release/babylon.module.d.ts
  11. 108 38
      dist/preview release/documentation.d.ts
  12. 1 1
      dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts
  13. 18 4
      dist/preview release/gui/babylon.gui.d.ts
  14. 106 55
      dist/preview release/gui/babylon.gui.js
  15. 1 1
      dist/preview release/gui/babylon.gui.js.map
  16. 1 1
      dist/preview release/gui/babylon.gui.min.js
  17. 36 8
      dist/preview release/gui/babylon.gui.module.d.ts
  18. 3 3
      dist/preview release/inspector/babylon.inspector.bundle.js
  19. 147 114
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  20. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  21. 29 5
      dist/preview release/inspector/babylon.inspector.d.ts
  22. 59 10
      dist/preview release/inspector/babylon.inspector.module.d.ts
  23. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  24. 40 39
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  25. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  26. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  27. 40 39
      dist/preview release/loaders/babylon.glTFFileLoader.js
  28. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  29. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  30. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  31. 1 1
      dist/preview release/loaders/babylon.stlFileLoader.min.js
  32. 40 39
      dist/preview release/loaders/babylonjs.loaders.js
  33. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  34. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  35. 36 0
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  36. 6 6
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  37. 212 6
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  38. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  39. 74 0
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  40. 1 1
      dist/preview release/packagesSizeBaseLine.json
  41. 402 30
      dist/preview release/serializers/babylon.glTF2Serializer.js
  42. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.js.map
  43. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  44. 38 2
      dist/preview release/serializers/babylonjs.serializers.d.ts
  45. 402 30
      dist/preview release/serializers/babylonjs.serializers.js
  46. 1 1
      dist/preview release/serializers/babylonjs.serializers.js.map
  47. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  48. 77 4
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  49. 103 62
      dist/preview release/viewer/babylon.module.d.ts
  50. 1 1
      dist/preview release/viewer/babylon.viewer.d.ts
  51. 521 521
      dist/preview release/viewer/babylon.viewer.js
  52. 14 14
      dist/preview release/viewer/babylon.viewer.max.js
  53. 1 1
      dist/preview release/viewer/babylon.viewer.module.d.ts
  54. 3 1
      dist/preview release/what's new.md
  55. 56 0
      gui/src/2D/controls/textBlock.ts
  56. 0 6
      gui/src/3D/materials/fluentMaterial.ts
  57. 118 0
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/canvasShader.ts
  58. 2 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/defaultTools/contrast.tsx
  59. 1 1
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/defaultTools/floodfill.ts
  60. 17 19
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/defaultTools/paintbrush.tsx
  61. 16 4
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/propertiesBar.tsx
  62. 4 4
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/textureCanvasComponent.tsx
  63. 51 136
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/textureCanvasManager.ts
  64. 13 14
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/textureEditor.scss
  65. 24 6
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/textureEditorComponent.tsx
  66. 18 37
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/toolBar.tsx
  67. 5 2
      inspector/src/inspector.ts
  68. 1 1
      loaders/src/glTF/2.0/Extensions/EXT_lights_image_based.ts
  69. 1 1
      loaders/src/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.ts
  70. 1 1
      loaders/src/glTF/2.0/Extensions/EXT_texture_webp.ts
  71. 1 1
      loaders/src/glTF/2.0/Extensions/ExtrasAsMetadata.ts
  72. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts
  73. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts
  74. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_materials_clearcoat.ts
  75. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_materials_ior.ts
  76. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts
  77. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts
  78. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_materials_specular.ts
  79. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_materials_transmission.ts
  80. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts
  81. 2 2
      loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts
  82. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_texture_basisu.ts
  83. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts
  84. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_xmp.ts
  85. 3 3
      loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts
  86. 1 1
      loaders/src/glTF/2.0/Extensions/MSFT_lod.ts
  87. 1 1
      loaders/src/glTF/2.0/Extensions/MSFT_minecraftMesh.ts
  88. 1 1
      loaders/src/glTF/2.0/Extensions/MSFT_sRGBFactors.ts
  89. 3 3
      loaders/src/glTF/2.0/glTFLoader.ts
  90. 1 1
      nodeEditor/src/components/nodeList/nodeListComponent.tsx
  91. 2 2
      package.json
  92. 1 1
      serializers/src/glTF/2.0/Extensions/KHR_lights_punctual.ts
  93. 14 1
      serializers/src/glTF/2.0/glTFMaterialExporter.ts
  94. 2 1
      src/Actions/action.ts
  95. 1 1
      src/Actions/actionManager.ts
  96. 15 3
      src/Bones/skeleton.ts
  97. 0 3
      src/Cameras/arcRotateCamera.ts
  98. 10 2
      src/Cameras/camera.ts
  99. 6 9
      src/Debug/axesViewer.ts
  100. 0 0
      src/Engines/Extensions/engine.textureSelector.ts

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

@@ -98,7 +98,7 @@ export class SceneManager {
     /**
      * Babylon's scene optimizer
      */
-    public sceneOptimizer: SceneOptimizer;
+    public sceneOptimizer?: SceneOptimizer;
     /**
      * Models displayed in this viewer.
      */
@@ -741,7 +741,7 @@ export class SceneManager {
 
         this.onSceneOptimizerConfiguredObservable.notifyObservers({
             sceneManager: this,
-            object: this.sceneOptimizer,
+            object: this.sceneOptimizer!,
             newConfiguration: optimizerConfig
         });
     }

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

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

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

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

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

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

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

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

+ 51 - 31
dist/preview release/babylon.d.ts

@@ -9414,7 +9414,7 @@ declare module BABYLON {
          * Internal only - manager for action
          * @hidden
          */
-        _actionManager: AbstractActionManager;
+        _actionManager: Nullable<AbstractActionManager>;
         /**
          * Adds action to chain of actions, may be a DoNothingAction
          * @param action defines the next action to execute
@@ -11663,7 +11663,6 @@ declare module BABYLON {
      * @see https://doc.babylonjs.com/how_to/how_to_use_procedural_textures
      */
     export class ProceduralTexture extends Texture {
-        isCube: boolean;
         /**
          * Define if the texture is enabled or not (disabled texture will not render)
          */
@@ -16021,6 +16020,8 @@ declare module BABYLON {
         _numBonesWithLinkedTransformNode: number;
         /** @hidden */
         _hasWaitingData: Nullable<boolean>;
+        /** @hidden */
+        _waitingOverrideMeshId: Nullable<string>;
         /**
          * Specifies if the skeleton should be serialized
          */
@@ -23287,6 +23288,8 @@ declare module BABYLON {
         private _delayedOnLoad;
         private _delayedOnError;
         private _mimeType?;
+        /** Returns the texture mime type if it was defined by a loader (undefined else) */
+        get mimeType(): string | undefined;
         /**
          * Observable triggered once the texture has been loaded.
          */
@@ -23468,7 +23471,6 @@ declare module BABYLON {
      * Actually, It is the base of lot of effects in the framework like post process, shadows, effect layers and rendering pipelines...
      */
     export class RenderTargetTexture extends Texture {
-        isCube: boolean;
         /**
          * The texture will only be rendered once which can be useful to improve performance if everything in your render is static for instance.
          */
@@ -23513,10 +23515,6 @@ declare module BABYLON {
          */
         renderSprites: boolean;
         /**
-         * Override the default coordinates mode to projection for RTT as it is the most common case for rendered textures.
-         */
-        coordinatesMode: number;
-        /**
          * Define the camera used to render the texture.
          */
         activeCamera: Nullable<Camera>;
@@ -23607,7 +23605,7 @@ declare module BABYLON {
         _generateMipMaps: boolean;
         protected _renderingManager: RenderingManager;
         /** @hidden */
-        _waitingRenderList: string[];
+        _waitingRenderList?: string[];
         protected _doNotChangeAspectRatio: boolean;
         protected _currentRefreshId: number;
         protected _refreshRate: number;
@@ -28282,6 +28280,14 @@ declare module BABYLON {
          */
         get source(): Nullable<Mesh>;
         /**
+         * Gets the list of clones of this mesh
+         * The scene must have been constructed with useClonedMeshMap=true for this to work!
+         * Note that useClonedMeshMap=true is the default setting
+         */
+        get cloneMeshMap(): Nullable<{
+            [id: string]: Mesh | undefined;
+        }>;
+        /**
          * Gets or sets a boolean indicating that this mesh does not use index buffer
          */
         get isUnIndexed(): boolean;
@@ -29374,11 +29380,13 @@ declare module BABYLON {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
+        protected _upVector: Vector3;
         /**
          * The vector the camera should consider as up.
          * (default is Vector3(0, 1, 0) aka Vector3.Up())
          */
-        upVector: Vector3;
+        set upVector(vec: Vector3);
+        get upVector(): Vector3;
         /**
          * Define the current limit on the left side for an orthographic camera
          * In scene unit
@@ -32122,11 +32130,13 @@ declare module BABYLON {
          * Gets or sets a boolean indicating that pointer move events must be supported on this mesh (false by default)
          */
         enablePointerMoveEvents: boolean;
+        private _renderingGroupId;
         /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see https://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
-        renderingGroupId: number;
+        get renderingGroupId(): number;
+        set renderingGroupId(value: number);
         private _material;
         /** Gets or sets current material */
         get material(): Nullable<Material>;
@@ -33858,7 +33868,7 @@ declare module BABYLON {
          * This is part of the texture as textures usually maps to one uv set.
          */
         coordinatesIndex: number;
-        private _coordinatesMode;
+        protected _coordinatesMode: number;
         /**
         * How a texture is mapped.
         *
@@ -33877,6 +33887,7 @@ declare module BABYLON {
         */
         set coordinatesMode(value: number);
         get coordinatesMode(): number;
+        private _wrapU;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -33884,7 +33895,9 @@ declare module BABYLON {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapU: number;
+        get wrapU(): number;
+        set wrapU(value: number);
+        private _wrapV;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -33892,7 +33905,8 @@ declare module BABYLON {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapV: number;
+        get wrapV(): number;
+        set wrapV(value: number);
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -39353,8 +39367,6 @@ declare module BABYLON {
          * The material properties need to be setup according to the type of texture in use.
          */
         environmentBRDFTexture: BaseTexture;
-        /** @hidden */
-        protected _environmentTexture: Nullable<BaseTexture>;
         /**
          * Texture used in all pbr material as the reflection texture.
          * As in the majority of the scene they are the same (exception for multi room and so on),
@@ -41132,6 +41144,13 @@ declare module BABYLON {
          */
         getMaterialByTags(tagsQuery: string, forEach?: (material: Material) => void): Material[];
         /**
+         * Get a list of transform nodes by tags
+         * @param tagsQuery defines the tags query to use
+         * @param forEach defines a predicate used to filter results
+         * @returns an array of TransformNode
+         */
+        getTransformNodesByTags(tagsQuery: string, forEach?: (transform: TransformNode) => void): TransformNode[];
+        /**
          * Overrides the default sort function applied in the renderging group to prepare the meshes.
          * This allowed control for front to back rendering or reversly depending of the special needs.
          *
@@ -41390,10 +41409,15 @@ declare module BABYLON {
          * Textures to keep.
          */
         textures: BaseTexture[];
+        /** @hidden */
+        protected _environmentTexture: Nullable<BaseTexture>;
         /**
-         * Environment texture for the scene
+         * Texture used in all pbr material as the reflection texture.
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
          */
-        environmentTexture: Nullable<BaseTexture>;
+        get environmentTexture(): Nullable<BaseTexture>;
+        set environmentTexture(value: Nullable<BaseTexture>);
         /**
          * The list of postprocesses added to the scene
          */
@@ -42812,7 +42836,6 @@ declare module BABYLON {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
-        protected _upVector: Vector3;
         protected _upToYMatrix: Matrix;
         protected _YToUpMatrix: Matrix;
         /**
@@ -50277,7 +50300,12 @@ declare module BABYLON {
         /**
          * Ratio for the scale of the gizmo (Default: 1)
          */
-        scaleRatio: number;
+        protected _scaleRatio: number;
+        /**
+         * Ratio for the scale of the gizmo (Default: 1)
+         */
+        set scaleRatio(value: number);
+        get scaleRatio(): number;
         /**
          * If a custom mesh has been set (Default: false)
          */
@@ -50299,10 +50327,12 @@ declare module BABYLON {
          * @param mesh The mesh to replace the default mesh of the gizmo
          */
         setCustomMesh(mesh: Mesh): void;
+        protected _updateGizmoRotationToMatchAttachedMesh: boolean;
         /**
          * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)
          */
-        updateGizmoRotationToMatchAttachedMesh: boolean;
+        set updateGizmoRotationToMatchAttachedMesh(value: boolean);
+        get updateGizmoRotationToMatchAttachedMesh(): boolean;
         /**
          * If set the gizmo's position will be updated to match the attached mesh each frame (Default: true)
          */
@@ -50422,9 +50452,7 @@ declare module BABYLON {
          */
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         /** Fires an event when any of it's sub gizmos are dragged */
         onDragStartObservable: Observable<unknown>;
         /** Fires an event when any of it's sub gizmos are released from dragging */
@@ -50535,7 +50563,7 @@ declare module BABYLON.Debug {
         /**
          * Gets the hosting scene
          */
-        scene: Scene;
+        scene: Nullable<Scene>;
         /**
          * Gets or sets a number used to scale line length
          */
@@ -53384,9 +53412,7 @@ declare module BABYLON {
         uniformScaleGizmo: AxisScaleGizmo;
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         private _uniformScalingMesh;
         private _octahedron;
         private _sensitivity;
@@ -60234,10 +60260,6 @@ declare module BABYLON {
          * The texture URL.
          */
         url: string;
-        /**
-         * The texture coordinates mode. As this texture is stored in a cube format, please modify carefully.
-         */
-        coordinatesMode: number;
         protected _isBlocking: boolean;
         /**
          * Sets wether or not the texture is blocking during loading.
@@ -61342,8 +61364,6 @@ declare module BABYLON {
         private _height;
         /** The URL to the image. */
         url: string;
-        /** The texture coordinates mode. As this texture is stored in a cube format, please modify carefully. */
-        coordinatesMode: number;
         /**
          * Instantiates an EquiRectangularCubeTexture from the following parameters.
          * @param url The location of the image

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/babylon.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2593 - 214
dist/preview release/babylon.max.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/babylon.max.js.map


+ 103 - 62
dist/preview release/babylon.module.d.ts

@@ -9534,6 +9534,7 @@ declare module "babylonjs/Actions/action" {
     import { Observable } from "babylonjs/Misc/observable";
     import { Condition } from "babylonjs/Actions/condition";
     import { AbstractActionManager } from "babylonjs/Actions/abstractActionManager";
+    import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
     import { ActionManager } from "babylonjs/Actions/actionManager";
     import { ActionEvent } from "babylonjs/Actions/actionEvent";
@@ -9573,7 +9574,7 @@ declare module "babylonjs/Actions/action" {
          * Internal only - manager for action
          * @hidden
          */
-        _actionManager: AbstractActionManager;
+        _actionManager: Nullable<AbstractActionManager>;
         /**
          * Adds action to chain of actions, may be a DoNothingAction
          * @param action defines the next action to execute
@@ -11924,7 +11925,6 @@ declare module "babylonjs/Materials/Textures/Procedurals/proceduralTexture" {
      * @see https://doc.babylonjs.com/how_to/how_to_use_procedural_textures
      */
     export class ProceduralTexture extends Texture {
-        isCube: boolean;
         /**
          * Define if the texture is enabled or not (disabled texture will not render)
          */
@@ -16443,6 +16443,8 @@ declare module "babylonjs/Bones/skeleton" {
         _numBonesWithLinkedTransformNode: number;
         /** @hidden */
         _hasWaitingData: Nullable<boolean>;
+        /** @hidden */
+        _waitingOverrideMeshId: Nullable<string>;
         /**
          * Specifies if the skeleton should be serialized
          */
@@ -24118,6 +24120,8 @@ declare module "babylonjs/Materials/Textures/texture" {
         private _delayedOnLoad;
         private _delayedOnError;
         private _mimeType?;
+        /** Returns the texture mime type if it was defined by a loader (undefined else) */
+        get mimeType(): string | undefined;
         /**
          * Observable triggered once the texture has been loaded.
          */
@@ -24320,7 +24324,6 @@ declare module "babylonjs/Materials/Textures/renderTargetTexture" {
      * Actually, It is the base of lot of effects in the framework like post process, shadows, effect layers and rendering pipelines...
      */
     export class RenderTargetTexture extends Texture {
-        isCube: boolean;
         /**
          * The texture will only be rendered once which can be useful to improve performance if everything in your render is static for instance.
          */
@@ -24365,10 +24368,6 @@ declare module "babylonjs/Materials/Textures/renderTargetTexture" {
          */
         renderSprites: boolean;
         /**
-         * Override the default coordinates mode to projection for RTT as it is the most common case for rendered textures.
-         */
-        coordinatesMode: number;
-        /**
          * Define the camera used to render the texture.
          */
         activeCamera: Nullable<Camera>;
@@ -24459,7 +24458,7 @@ declare module "babylonjs/Materials/Textures/renderTargetTexture" {
         _generateMipMaps: boolean;
         protected _renderingManager: RenderingManager;
         /** @hidden */
-        _waitingRenderList: string[];
+        _waitingRenderList?: string[];
         protected _doNotChangeAspectRatio: boolean;
         protected _currentRefreshId: number;
         protected _refreshRate: number;
@@ -29300,6 +29299,14 @@ declare module "babylonjs/Meshes/mesh" {
          */
         get source(): Nullable<Mesh>;
         /**
+         * Gets the list of clones of this mesh
+         * The scene must have been constructed with useClonedMeshMap=true for this to work!
+         * Note that useClonedMeshMap=true is the default setting
+         */
+        get cloneMeshMap(): Nullable<{
+            [id: string]: Mesh | undefined;
+        }>;
+        /**
          * Gets or sets a boolean indicating that this mesh does not use index buffer
          */
         get isUnIndexed(): boolean;
@@ -30407,11 +30414,13 @@ declare module "babylonjs/Cameras/camera" {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
+        protected _upVector: Vector3;
         /**
          * The vector the camera should consider as up.
          * (default is Vector3(0, 1, 0) aka Vector3.Up())
          */
-        upVector: Vector3;
+        set upVector(vec: Vector3);
+        get upVector(): Vector3;
         /**
          * Define the current limit on the left side for an orthographic camera
          * In scene unit
@@ -33276,11 +33285,13 @@ declare module "babylonjs/Meshes/abstractMesh" {
          * Gets or sets a boolean indicating that pointer move events must be supported on this mesh (false by default)
          */
         enablePointerMoveEvents: boolean;
+        private _renderingGroupId;
         /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see https://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
-        renderingGroupId: number;
+        get renderingGroupId(): number;
+        set renderingGroupId(value: number);
         private _material;
         /** Gets or sets current material */
         get material(): Nullable<Material>;
@@ -35065,7 +35076,7 @@ declare module "babylonjs/Materials/Textures/baseTexture" {
          * This is part of the texture as textures usually maps to one uv set.
          */
         coordinatesIndex: number;
-        private _coordinatesMode;
+        protected _coordinatesMode: number;
         /**
         * How a texture is mapped.
         *
@@ -35084,6 +35095,7 @@ declare module "babylonjs/Materials/Textures/baseTexture" {
         */
         set coordinatesMode(value: number);
         get coordinatesMode(): number;
+        private _wrapU;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -35091,7 +35103,9 @@ declare module "babylonjs/Materials/Textures/baseTexture" {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapU: number;
+        get wrapU(): number;
+        set wrapU(value: number);
+        private _wrapV;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -35099,7 +35113,8 @@ declare module "babylonjs/Materials/Textures/baseTexture" {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapV: number;
+        get wrapV(): number;
+        set wrapV(value: number);
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -40731,8 +40746,6 @@ declare module "babylonjs/scene" {
          * The material properties need to be setup according to the type of texture in use.
          */
         environmentBRDFTexture: BaseTexture;
-        /** @hidden */
-        protected _environmentTexture: Nullable<BaseTexture>;
         /**
          * Texture used in all pbr material as the reflection texture.
          * As in the majority of the scene they are the same (exception for multi room and so on),
@@ -42510,6 +42523,13 @@ declare module "babylonjs/scene" {
          */
         getMaterialByTags(tagsQuery: string, forEach?: (material: Material) => void): Material[];
         /**
+         * Get a list of transform nodes by tags
+         * @param tagsQuery defines the tags query to use
+         * @param forEach defines a predicate used to filter results
+         * @returns an array of TransformNode
+         */
+        getTransformNodesByTags(tagsQuery: string, forEach?: (transform: TransformNode) => void): TransformNode[];
+        /**
          * Overrides the default sort function applied in the renderging group to prepare the meshes.
          * This allowed control for front to back rendering or reversly depending of the special needs.
          *
@@ -42795,10 +42815,15 @@ declare module "babylonjs/abstractScene" {
          * Textures to keep.
          */
         textures: BaseTexture[];
+        /** @hidden */
+        protected _environmentTexture: Nullable<BaseTexture>;
         /**
-         * Environment texture for the scene
+         * Texture used in all pbr material as the reflection texture.
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
          */
-        environmentTexture: Nullable<BaseTexture>;
+        get environmentTexture(): Nullable<BaseTexture>;
+        set environmentTexture(value: Nullable<BaseTexture>);
         /**
          * The list of postprocesses added to the scene
          */
@@ -44312,7 +44337,6 @@ declare module "babylonjs/Cameras/arcRotateCamera" {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
-        protected _upVector: Vector3;
         protected _upToYMatrix: Matrix;
         protected _YToUpMatrix: Matrix;
         /**
@@ -52255,7 +52279,12 @@ declare module "babylonjs/Gizmos/gizmo" {
         /**
          * Ratio for the scale of the gizmo (Default: 1)
          */
-        scaleRatio: number;
+        protected _scaleRatio: number;
+        /**
+         * Ratio for the scale of the gizmo (Default: 1)
+         */
+        set scaleRatio(value: number);
+        get scaleRatio(): number;
         /**
          * If a custom mesh has been set (Default: false)
          */
@@ -52277,10 +52306,12 @@ declare module "babylonjs/Gizmos/gizmo" {
          * @param mesh The mesh to replace the default mesh of the gizmo
          */
         setCustomMesh(mesh: Mesh): void;
+        protected _updateGizmoRotationToMatchAttachedMesh: boolean;
         /**
          * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)
          */
-        updateGizmoRotationToMatchAttachedMesh: boolean;
+        set updateGizmoRotationToMatchAttachedMesh(value: boolean);
+        get updateGizmoRotationToMatchAttachedMesh(): boolean;
         /**
          * If set the gizmo's position will be updated to match the attached mesh each frame (Default: true)
          */
@@ -52421,9 +52452,7 @@ declare module "babylonjs/Gizmos/positionGizmo" {
          */
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         /** Fires an event when any of it's sub gizmos are dragged */
         onDragStartObservable: Observable<unknown>;
         /** Fires an event when any of it's sub gizmos are released from dragging */
@@ -52550,7 +52579,7 @@ declare module "babylonjs/Debug/axesViewer" {
         /**
          * Gets the hosting scene
          */
-        scene: Scene;
+        scene: Nullable<Scene>;
         /**
          * Gets or sets a number used to scale line length
          */
@@ -55638,9 +55667,7 @@ declare module "babylonjs/Gizmos/scaleGizmo" {
         uniformScaleGizmo: AxisScaleGizmo;
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         private _uniformScalingMesh;
         private _octahedron;
         private _sensitivity;
@@ -63036,10 +63063,6 @@ declare module "babylonjs/Materials/Textures/hdrCubeTexture" {
          * The texture URL.
          */
         url: string;
-        /**
-         * The texture coordinates mode. As this texture is stored in a cube format, please modify carefully.
-         */
-        coordinatesMode: number;
         protected _isBlocking: boolean;
         /**
          * Sets wether or not the texture is blocking during loading.
@@ -64219,8 +64242,6 @@ declare module "babylonjs/Materials/Textures/equiRectangularCubeTexture" {
         private _height;
         /** The URL to the image. */
         url: string;
-        /** The texture coordinates mode. As this texture is stored in a cube format, please modify carefully. */
-        coordinatesMode: number;
         /**
          * Instantiates an EquiRectangularCubeTexture from the following parameters.
          * @param url The location of the image
@@ -89036,7 +89057,7 @@ declare module BABYLON {
          * Internal only - manager for action
          * @hidden
          */
-        _actionManager: AbstractActionManager;
+        _actionManager: Nullable<AbstractActionManager>;
         /**
          * Adds action to chain of actions, may be a DoNothingAction
          * @param action defines the next action to execute
@@ -91285,7 +91306,6 @@ declare module BABYLON {
      * @see https://doc.babylonjs.com/how_to/how_to_use_procedural_textures
      */
     export class ProceduralTexture extends Texture {
-        isCube: boolean;
         /**
          * Define if the texture is enabled or not (disabled texture will not render)
          */
@@ -95643,6 +95663,8 @@ declare module BABYLON {
         _numBonesWithLinkedTransformNode: number;
         /** @hidden */
         _hasWaitingData: Nullable<boolean>;
+        /** @hidden */
+        _waitingOverrideMeshId: Nullable<string>;
         /**
          * Specifies if the skeleton should be serialized
          */
@@ -102909,6 +102931,8 @@ declare module BABYLON {
         private _delayedOnLoad;
         private _delayedOnError;
         private _mimeType?;
+        /** Returns the texture mime type if it was defined by a loader (undefined else) */
+        get mimeType(): string | undefined;
         /**
          * Observable triggered once the texture has been loaded.
          */
@@ -103090,7 +103114,6 @@ declare module BABYLON {
      * Actually, It is the base of lot of effects in the framework like post process, shadows, effect layers and rendering pipelines...
      */
     export class RenderTargetTexture extends Texture {
-        isCube: boolean;
         /**
          * The texture will only be rendered once which can be useful to improve performance if everything in your render is static for instance.
          */
@@ -103135,10 +103158,6 @@ declare module BABYLON {
          */
         renderSprites: boolean;
         /**
-         * Override the default coordinates mode to projection for RTT as it is the most common case for rendered textures.
-         */
-        coordinatesMode: number;
-        /**
          * Define the camera used to render the texture.
          */
         activeCamera: Nullable<Camera>;
@@ -103229,7 +103248,7 @@ declare module BABYLON {
         _generateMipMaps: boolean;
         protected _renderingManager: RenderingManager;
         /** @hidden */
-        _waitingRenderList: string[];
+        _waitingRenderList?: string[];
         protected _doNotChangeAspectRatio: boolean;
         protected _currentRefreshId: number;
         protected _refreshRate: number;
@@ -107904,6 +107923,14 @@ declare module BABYLON {
          */
         get source(): Nullable<Mesh>;
         /**
+         * Gets the list of clones of this mesh
+         * The scene must have been constructed with useClonedMeshMap=true for this to work!
+         * Note that useClonedMeshMap=true is the default setting
+         */
+        get cloneMeshMap(): Nullable<{
+            [id: string]: Mesh | undefined;
+        }>;
+        /**
          * Gets or sets a boolean indicating that this mesh does not use index buffer
          */
         get isUnIndexed(): boolean;
@@ -108996,11 +109023,13 @@ declare module BABYLON {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
+        protected _upVector: Vector3;
         /**
          * The vector the camera should consider as up.
          * (default is Vector3(0, 1, 0) aka Vector3.Up())
          */
-        upVector: Vector3;
+        set upVector(vec: Vector3);
+        get upVector(): Vector3;
         /**
          * Define the current limit on the left side for an orthographic camera
          * In scene unit
@@ -111744,11 +111773,13 @@ declare module BABYLON {
          * Gets or sets a boolean indicating that pointer move events must be supported on this mesh (false by default)
          */
         enablePointerMoveEvents: boolean;
+        private _renderingGroupId;
         /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see https://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
-        renderingGroupId: number;
+        get renderingGroupId(): number;
+        set renderingGroupId(value: number);
         private _material;
         /** Gets or sets current material */
         get material(): Nullable<Material>;
@@ -113480,7 +113511,7 @@ declare module BABYLON {
          * This is part of the texture as textures usually maps to one uv set.
          */
         coordinatesIndex: number;
-        private _coordinatesMode;
+        protected _coordinatesMode: number;
         /**
         * How a texture is mapped.
         *
@@ -113499,6 +113530,7 @@ declare module BABYLON {
         */
         set coordinatesMode(value: number);
         get coordinatesMode(): number;
+        private _wrapU;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -113506,7 +113538,9 @@ declare module BABYLON {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapU: number;
+        get wrapU(): number;
+        set wrapU(value: number);
+        private _wrapV;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -113514,7 +113548,8 @@ declare module BABYLON {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapV: number;
+        get wrapV(): number;
+        set wrapV(value: number);
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -118975,8 +119010,6 @@ declare module BABYLON {
          * The material properties need to be setup according to the type of texture in use.
          */
         environmentBRDFTexture: BaseTexture;
-        /** @hidden */
-        protected _environmentTexture: Nullable<BaseTexture>;
         /**
          * Texture used in all pbr material as the reflection texture.
          * As in the majority of the scene they are the same (exception for multi room and so on),
@@ -120754,6 +120787,13 @@ declare module BABYLON {
          */
         getMaterialByTags(tagsQuery: string, forEach?: (material: Material) => void): Material[];
         /**
+         * Get a list of transform nodes by tags
+         * @param tagsQuery defines the tags query to use
+         * @param forEach defines a predicate used to filter results
+         * @returns an array of TransformNode
+         */
+        getTransformNodesByTags(tagsQuery: string, forEach?: (transform: TransformNode) => void): TransformNode[];
+        /**
          * Overrides the default sort function applied in the renderging group to prepare the meshes.
          * This allowed control for front to back rendering or reversly depending of the special needs.
          *
@@ -121012,10 +121052,15 @@ declare module BABYLON {
          * Textures to keep.
          */
         textures: BaseTexture[];
+        /** @hidden */
+        protected _environmentTexture: Nullable<BaseTexture>;
         /**
-         * Environment texture for the scene
+         * Texture used in all pbr material as the reflection texture.
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
          */
-        environmentTexture: Nullable<BaseTexture>;
+        get environmentTexture(): Nullable<BaseTexture>;
+        set environmentTexture(value: Nullable<BaseTexture>);
         /**
          * The list of postprocesses added to the scene
          */
@@ -122434,7 +122479,6 @@ declare module BABYLON {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
-        protected _upVector: Vector3;
         protected _upToYMatrix: Matrix;
         protected _YToUpMatrix: Matrix;
         /**
@@ -129899,7 +129943,12 @@ declare module BABYLON {
         /**
          * Ratio for the scale of the gizmo (Default: 1)
          */
-        scaleRatio: number;
+        protected _scaleRatio: number;
+        /**
+         * Ratio for the scale of the gizmo (Default: 1)
+         */
+        set scaleRatio(value: number);
+        get scaleRatio(): number;
         /**
          * If a custom mesh has been set (Default: false)
          */
@@ -129921,10 +129970,12 @@ declare module BABYLON {
          * @param mesh The mesh to replace the default mesh of the gizmo
          */
         setCustomMesh(mesh: Mesh): void;
+        protected _updateGizmoRotationToMatchAttachedMesh: boolean;
         /**
          * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)
          */
-        updateGizmoRotationToMatchAttachedMesh: boolean;
+        set updateGizmoRotationToMatchAttachedMesh(value: boolean);
+        get updateGizmoRotationToMatchAttachedMesh(): boolean;
         /**
          * If set the gizmo's position will be updated to match the attached mesh each frame (Default: true)
          */
@@ -130044,9 +130095,7 @@ declare module BABYLON {
          */
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         /** Fires an event when any of it's sub gizmos are dragged */
         onDragStartObservable: Observable<unknown>;
         /** Fires an event when any of it's sub gizmos are released from dragging */
@@ -130157,7 +130206,7 @@ declare module BABYLON.Debug {
         /**
          * Gets the hosting scene
          */
-        scene: Scene;
+        scene: Nullable<Scene>;
         /**
          * Gets or sets a number used to scale line length
          */
@@ -133006,9 +133055,7 @@ declare module BABYLON {
         uniformScaleGizmo: AxisScaleGizmo;
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         private _uniformScalingMesh;
         private _octahedron;
         private _sensitivity;
@@ -139856,10 +139903,6 @@ declare module BABYLON {
          * The texture URL.
          */
         url: string;
-        /**
-         * The texture coordinates mode. As this texture is stored in a cube format, please modify carefully.
-         */
-        coordinatesMode: number;
         protected _isBlocking: boolean;
         /**
          * Sets wether or not the texture is blocking during loading.
@@ -140964,8 +141007,6 @@ declare module BABYLON {
         private _height;
         /** The URL to the image. */
         url: string;
-        /** The texture coordinates mode. As this texture is stored in a cube format, please modify carefully. */
-        coordinatesMode: number;
         /**
          * Instantiates an EquiRectangularCubeTexture from the following parameters.
          * @param url The location of the image

+ 108 - 38
dist/preview release/documentation.d.ts

@@ -9414,7 +9414,7 @@ declare module BABYLON {
          * Internal only - manager for action
          * @hidden
          */
-        _actionManager: AbstractActionManager;
+        _actionManager: Nullable<AbstractActionManager>;
         /**
          * Adds action to chain of actions, may be a DoNothingAction
          * @param action defines the next action to execute
@@ -11663,7 +11663,6 @@ declare module BABYLON {
      * @see https://doc.babylonjs.com/how_to/how_to_use_procedural_textures
      */
     export class ProceduralTexture extends Texture {
-        isCube: boolean;
         /**
          * Define if the texture is enabled or not (disabled texture will not render)
          */
@@ -16021,6 +16020,8 @@ declare module BABYLON {
         _numBonesWithLinkedTransformNode: number;
         /** @hidden */
         _hasWaitingData: Nullable<boolean>;
+        /** @hidden */
+        _waitingOverrideMeshId: Nullable<string>;
         /**
          * Specifies if the skeleton should be serialized
          */
@@ -23287,6 +23288,8 @@ declare module BABYLON {
         private _delayedOnLoad;
         private _delayedOnError;
         private _mimeType?;
+        /** Returns the texture mime type if it was defined by a loader (undefined else) */
+        get mimeType(): string | undefined;
         /**
          * Observable triggered once the texture has been loaded.
          */
@@ -23468,7 +23471,6 @@ declare module BABYLON {
      * Actually, It is the base of lot of effects in the framework like post process, shadows, effect layers and rendering pipelines...
      */
     export class RenderTargetTexture extends Texture {
-        isCube: boolean;
         /**
          * The texture will only be rendered once which can be useful to improve performance if everything in your render is static for instance.
          */
@@ -23513,10 +23515,6 @@ declare module BABYLON {
          */
         renderSprites: boolean;
         /**
-         * Override the default coordinates mode to projection for RTT as it is the most common case for rendered textures.
-         */
-        coordinatesMode: number;
-        /**
          * Define the camera used to render the texture.
          */
         activeCamera: Nullable<Camera>;
@@ -23607,7 +23605,7 @@ declare module BABYLON {
         _generateMipMaps: boolean;
         protected _renderingManager: RenderingManager;
         /** @hidden */
-        _waitingRenderList: string[];
+        _waitingRenderList?: string[];
         protected _doNotChangeAspectRatio: boolean;
         protected _currentRefreshId: number;
         protected _refreshRate: number;
@@ -28282,6 +28280,14 @@ declare module BABYLON {
          */
         get source(): Nullable<Mesh>;
         /**
+         * Gets the list of clones of this mesh
+         * The scene must have been constructed with useClonedMeshMap=true for this to work!
+         * Note that useClonedMeshMap=true is the default setting
+         */
+        get cloneMeshMap(): Nullable<{
+            [id: string]: Mesh | undefined;
+        }>;
+        /**
          * Gets or sets a boolean indicating that this mesh does not use index buffer
          */
         get isUnIndexed(): boolean;
@@ -29374,11 +29380,13 @@ declare module BABYLON {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
+        protected _upVector: Vector3;
         /**
          * The vector the camera should consider as up.
          * (default is Vector3(0, 1, 0) aka Vector3.Up())
          */
-        upVector: Vector3;
+        set upVector(vec: Vector3);
+        get upVector(): Vector3;
         /**
          * Define the current limit on the left side for an orthographic camera
          * In scene unit
@@ -32122,11 +32130,13 @@ declare module BABYLON {
          * Gets or sets a boolean indicating that pointer move events must be supported on this mesh (false by default)
          */
         enablePointerMoveEvents: boolean;
+        private _renderingGroupId;
         /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see https://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
-        renderingGroupId: number;
+        get renderingGroupId(): number;
+        set renderingGroupId(value: number);
         private _material;
         /** Gets or sets current material */
         get material(): Nullable<Material>;
@@ -33858,7 +33868,7 @@ declare module BABYLON {
          * This is part of the texture as textures usually maps to one uv set.
          */
         coordinatesIndex: number;
-        private _coordinatesMode;
+        protected _coordinatesMode: number;
         /**
         * How a texture is mapped.
         *
@@ -33877,6 +33887,7 @@ declare module BABYLON {
         */
         set coordinatesMode(value: number);
         get coordinatesMode(): number;
+        private _wrapU;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -33884,7 +33895,9 @@ declare module BABYLON {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapU: number;
+        get wrapU(): number;
+        set wrapU(value: number);
+        private _wrapV;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -33892,7 +33905,8 @@ declare module BABYLON {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapV: number;
+        get wrapV(): number;
+        set wrapV(value: number);
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -39353,8 +39367,6 @@ declare module BABYLON {
          * The material properties need to be setup according to the type of texture in use.
          */
         environmentBRDFTexture: BaseTexture;
-        /** @hidden */
-        protected _environmentTexture: Nullable<BaseTexture>;
         /**
          * Texture used in all pbr material as the reflection texture.
          * As in the majority of the scene they are the same (exception for multi room and so on),
@@ -41132,6 +41144,13 @@ declare module BABYLON {
          */
         getMaterialByTags(tagsQuery: string, forEach?: (material: Material) => void): Material[];
         /**
+         * Get a list of transform nodes by tags
+         * @param tagsQuery defines the tags query to use
+         * @param forEach defines a predicate used to filter results
+         * @returns an array of TransformNode
+         */
+        getTransformNodesByTags(tagsQuery: string, forEach?: (transform: TransformNode) => void): TransformNode[];
+        /**
          * Overrides the default sort function applied in the renderging group to prepare the meshes.
          * This allowed control for front to back rendering or reversly depending of the special needs.
          *
@@ -41390,10 +41409,15 @@ declare module BABYLON {
          * Textures to keep.
          */
         textures: BaseTexture[];
+        /** @hidden */
+        protected _environmentTexture: Nullable<BaseTexture>;
         /**
-         * Environment texture for the scene
+         * Texture used in all pbr material as the reflection texture.
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
          */
-        environmentTexture: Nullable<BaseTexture>;
+        get environmentTexture(): Nullable<BaseTexture>;
+        set environmentTexture(value: Nullable<BaseTexture>);
         /**
          * The list of postprocesses added to the scene
          */
@@ -42812,7 +42836,6 @@ declare module BABYLON {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
-        protected _upVector: Vector3;
         protected _upToYMatrix: Matrix;
         protected _YToUpMatrix: Matrix;
         /**
@@ -50277,7 +50300,12 @@ declare module BABYLON {
         /**
          * Ratio for the scale of the gizmo (Default: 1)
          */
-        scaleRatio: number;
+        protected _scaleRatio: number;
+        /**
+         * Ratio for the scale of the gizmo (Default: 1)
+         */
+        set scaleRatio(value: number);
+        get scaleRatio(): number;
         /**
          * If a custom mesh has been set (Default: false)
          */
@@ -50299,10 +50327,12 @@ declare module BABYLON {
          * @param mesh The mesh to replace the default mesh of the gizmo
          */
         setCustomMesh(mesh: Mesh): void;
+        protected _updateGizmoRotationToMatchAttachedMesh: boolean;
         /**
          * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)
          */
-        updateGizmoRotationToMatchAttachedMesh: boolean;
+        set updateGizmoRotationToMatchAttachedMesh(value: boolean);
+        get updateGizmoRotationToMatchAttachedMesh(): boolean;
         /**
          * If set the gizmo's position will be updated to match the attached mesh each frame (Default: true)
          */
@@ -50422,9 +50452,7 @@ declare module BABYLON {
          */
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         /** Fires an event when any of it's sub gizmos are dragged */
         onDragStartObservable: Observable<unknown>;
         /** Fires an event when any of it's sub gizmos are released from dragging */
@@ -50535,7 +50563,7 @@ declare module BABYLON.Debug {
         /**
          * Gets the hosting scene
          */
-        scene: Scene;
+        scene: Nullable<Scene>;
         /**
          * Gets or sets a number used to scale line length
          */
@@ -53384,9 +53412,7 @@ declare module BABYLON {
         uniformScaleGizmo: AxisScaleGizmo;
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         private _uniformScalingMesh;
         private _octahedron;
         private _sensitivity;
@@ -60234,10 +60260,6 @@ declare module BABYLON {
          * The texture URL.
          */
         url: string;
-        /**
-         * The texture coordinates mode. As this texture is stored in a cube format, please modify carefully.
-         */
-        coordinatesMode: number;
         protected _isBlocking: boolean;
         /**
          * Sets wether or not the texture is blocking during loading.
@@ -61342,8 +61364,6 @@ declare module BABYLON {
         private _height;
         /** The URL to the image. */
         url: string;
-        /** The texture coordinates mode. As this texture is stored in a cube format, please modify carefully. */
-        coordinatesMode: number;
         /**
          * Instantiates an EquiRectangularCubeTexture from the following parameters.
          * @param url The location of the image
@@ -77524,6 +77544,8 @@ declare module BABYLON.GUI {
         private _lineSpacing;
         private _outlineWidth;
         private _outlineColor;
+        private _underline;
+        private _lineThrough;
         /**
         * An event triggered after the text is changed
         */
@@ -77597,6 +77619,22 @@ declare module BABYLON.GUI {
          */
         set outlineWidth(value: number);
         /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        get underline(): boolean;
+        /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        set underline(value: boolean);
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        get lineThrough(): boolean;
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        set lineThrough(value: boolean);
+        /**
          * Gets or sets outlineColor of the text to display
          */
         get outlineColor(): string;
@@ -79978,10 +80016,6 @@ declare module BABYLON.GUI {
          */
         innerGlowColor: BABYLON.Color3;
         /**
-         * Gets or sets alpha value (default is 1.0)
-         */
-        alpha: number;
-        /**
          * Gets or sets the albedo color (Default is BABYLON.Color3(0.3, 0.35, 0.4))
          */
         albedoColor: BABYLON.Color3;
@@ -83282,6 +83316,7 @@ declare module BABYLON.GLTF2.Exporter {
         static _GetRightHandedQuaternionArrayFromRef(quaternion: number[]): void;
         static _NormalizeTangentFromRef(tangent: Vector4): void;
         static _GetRightHandedMatrixFromRef(matrix: Matrix): void;
+        static _GetDataAccessorElementCount(accessorType: AccessorType): 1 | 3 | 2 | 4 | 9 | 16;
     }
 }
 declare module BABYLON.GLTF2.Exporter {
@@ -83502,6 +83537,16 @@ declare module BABYLON.GLTF2.Exporter {
          */
         writeAttributeData(vertexBufferKind: string, attributeComponentKind: AccessorComponentType, meshAttributeArray: FloatArray, stride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean, babylonTransformNode: TransformNode): void;
         /**
+         * Writes mesh attribute data to a data buffer
+         * Returns the bytelength of the data
+         * @param vertexBufferKind Indicates what kind of vertex data is being passed in
+         * @param meshAttributeArray Array containing the attribute data
+         * @param byteStride Specifies the space between data
+         * @param binaryWriter The buffer to write the binary data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
+         */
+        writeMorphTargetAttributeData(vertexBufferKind: string, attributeComponentKind: AccessorComponentType, meshPrimitive: SubMesh, morphTarget: MorphTarget, meshAttributeArray: FloatArray, morphTargetAttributeArray: FloatArray, stride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean, minMax?: any): void;
+        /**
          * Generates glTF json data
          * @param shouldUseGlb Indicates whether the json should be written for a glb file
          * @param glTFPrefix Text to use when prefixing a glTF file
@@ -83549,6 +83594,14 @@ declare module BABYLON.GLTF2.Exporter {
          */
         private createBufferViewKind;
         /**
+     * Creates a bufferview based on the vertices type for the Babylon mesh
+     * @param babylonSubMesh The Babylon submesh that the morph target is applied to
+     * @param babylonMorphTarget the morph target to be exported
+     * @param binaryWriter The buffer to write the bufferview data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
+     */
+        private setMorphTargetAttributes;
+        /**
          * The primitive mode of the Babylon mesh
          * @param babylonMesh The BabylonJS mesh
          */
@@ -83724,7 +83777,7 @@ declare module BABYLON.GLTF2.Exporter {
         /**
          * The glTF accessor type for the data.
          */
-        dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4;
+        dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4 | AccessorType.SCALAR;
         /**
          * Specifies if quaternions should be used.
          */
@@ -83766,8 +83819,25 @@ declare module BABYLON.GLTF2.Exporter {
             [key: number]: number;
         }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
         /**
+     * @ignore
+     * Create individual morph animations from the mesh's morph target animation tracks
+     * @param babylonNode
+     * @param runtimeGLTFAnimation
+     * @param idleGLTFAnimations
+     * @param nodeMap
+     * @param nodes
+     * @param binaryWriter
+     * @param bufferViews
+     * @param accessors
+     * @param convertToRightHandedSystem
+     * @param animationSampleRate
+     */
+        static _CreateMorphTargetAnimationFromMorphTargets(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
+            [key: number]: number;
+        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
+        /**
          * @ignore
-         * Create node animations from the animation groups
+         * Create node and morph animations from the animation groups
          * @param babylonScene
          * @param glTFAnimations
          * @param nodeMap
@@ -85062,7 +85132,7 @@ declare module BABYLON.GLTF2 {
 
     /** @hidden */
     interface IKHRMaterialVariants_Mapping extends IProperty {
-        mapping: Array<{
+        mappings: Array<{
             variants: number[];
             material: number;
         }>;

+ 1 - 1
dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts

@@ -1062,7 +1062,7 @@ declare module BABYLON.GLTF2 {
 
     /** @hidden */
     interface IKHRMaterialVariants_Mapping extends IProperty {
-        mapping: Array<{
+        mappings: Array<{
             variants: number[];
             material: number;
         }>;

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

@@ -1438,6 +1438,8 @@ declare module BABYLON.GUI {
         private _lineSpacing;
         private _outlineWidth;
         private _outlineColor;
+        private _underline;
+        private _lineThrough;
         /**
         * An event triggered after the text is changed
         */
@@ -1511,6 +1513,22 @@ declare module BABYLON.GUI {
          */
         set outlineWidth(value: number);
         /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        get underline(): boolean;
+        /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        set underline(value: boolean);
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        get lineThrough(): boolean;
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        set lineThrough(value: boolean);
+        /**
          * Gets or sets outlineColor of the text to display
          */
         get outlineColor(): string;
@@ -3892,10 +3910,6 @@ declare module BABYLON.GUI {
          */
         innerGlowColor: BABYLON.Color3;
         /**
-         * Gets or sets alpha value (default is 1.0)
-         */
-        alpha: number;
-        /**
          * Gets or sets the albedo color (Default is BABYLON.Color3(0.3, 0.35, 0.4))
          */
         albedoColor: BABYLON.Color3;

+ 106 - 55
dist/preview release/gui/babylon.gui.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-gui"] = factory(require("babylonjs"));
 	else
 		root["BABYLON"] = root["BABYLON"] || {}, root["BABYLON"]["GUI"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_perfCounter__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -400,7 +400,7 @@ module.exports = g;
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTextureInstrumentation", function() { return AdvancedDynamicTextureInstrumentation; });
-/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/perfCounter */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/perfCounter */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -543,7 +543,7 @@ var AdvancedDynamicTextureInstrumentation = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTexture", function() { return AdvancedDynamicTexture; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _controls_container__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controls/container */ "./2D/controls/container.ts");
 /* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./style */ "./2D/style.ts");
@@ -1530,7 +1530,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _textBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./textBlock */ "./2D/controls/textBlock.ts");
 /* harmony import */ var _image__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./image */ "./2D/controls/image.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__);
 
 
@@ -1762,7 +1762,7 @@ babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTy
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Checkbox", function() { return Checkbox; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
@@ -1945,7 +1945,7 @@ babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorPicker", function() { return ColorPicker; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _inputText__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./inputText */ "./2D/controls/inputText.ts");
@@ -3338,7 +3338,7 @@ babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container", function() { return Container; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../measure */ "./2D/measure.ts");
@@ -3753,7 +3753,7 @@ babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredTypes
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Control", function() { return Control; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../measure */ "./2D/measure.ts");
@@ -5701,7 +5701,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DisplayGrid", function() { return DisplayGrid; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -5934,7 +5934,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__);
 
 
@@ -6031,7 +6031,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__);
 
 
@@ -6489,7 +6489,7 @@ babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes[
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Image", function() { return Image; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 
@@ -7426,7 +7426,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputPassword", function() { return InputPassword; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _inputText__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./inputText */ "./2D/controls/inputText.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -7465,7 +7465,7 @@ babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTy
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputText", function() { return InputText; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -8478,7 +8478,7 @@ babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Line", function() { return Line; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -8749,7 +8749,7 @@ babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].Registere
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiLine", function() { return MultiLine; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/abstractMesh */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/abstractMesh */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _multiLinePoint__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../multiLinePoint */ "./2D/multiLinePoint.ts");
@@ -9019,7 +9019,7 @@ babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].Registe
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RadioButton", function() { return RadioButton; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
@@ -9226,7 +9226,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Rectangle", function() { return Rectangle; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -9376,7 +9376,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _scrollViewerWindow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./scrollViewerWindow */ "./2D/controls/scrollViewers/scrollViewerWindow.ts");
 /* harmony import */ var _sliders_scrollBar__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../sliders/scrollBar */ "./2D/controls/sliders/scrollBar.ts");
 /* harmony import */ var _sliders_imageScrollBar__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../sliders/imageScrollBar */ "./2D/controls/sliders/imageScrollBar.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__);
 
 
@@ -10999,7 +10999,7 @@ var SelectionPanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSlider", function() { return BaseSlider; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -11333,7 +11333,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _baseSlider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./baseSlider */ "./2D/controls/sliders/baseSlider.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../measure */ "./2D/measure.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__);
 
 
@@ -11926,7 +11926,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Slider", function() { return Slider; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _baseSlider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./baseSlider */ "./2D/controls/sliders/baseSlider.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -12181,7 +12181,7 @@ babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTy
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StackPanel", function() { return StackPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
@@ -12449,7 +12449,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextWrapping", function() { return TextWrapping; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextBlock", function() { return TextBlock; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
@@ -12502,6 +12502,8 @@ var TextBlock = /** @class */ (function (_super) {
         _this._lineSpacing = new _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__["ValueAndUnit"](0);
         _this._outlineWidth = 0;
         _this._outlineColor = "white";
+        _this._underline = false;
+        _this._lineThrough = false;
         /**
         * An event triggered after the text is changed
         */
@@ -12666,6 +12668,46 @@ var TextBlock = /** @class */ (function (_super) {
         enumerable: false,
         configurable: true
     });
+    Object.defineProperty(TextBlock.prototype, "underline", {
+        /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        get: function () {
+            return this._underline;
+        },
+        /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        set: function (value) {
+            if (this._underline === value) {
+                return;
+            }
+            this._underline = value;
+            this._markAsDirty();
+        },
+        enumerable: false,
+        configurable: true
+    });
+    Object.defineProperty(TextBlock.prototype, "lineThrough", {
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        get: function () {
+            return this._lineThrough;
+        },
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        set: function (value) {
+            if (this._lineThrough === value) {
+                return;
+            }
+            this._lineThrough = value;
+            this._markAsDirty();
+        },
+        enumerable: false,
+        configurable: true
+    });
     Object.defineProperty(TextBlock.prototype, "outlineColor", {
         /**
          * Gets or sets outlineColor of the text to display
@@ -12753,6 +12795,22 @@ var TextBlock = /** @class */ (function (_super) {
             context.strokeText(text, this._currentMeasure.left + x, y);
         }
         context.fillText(text, this._currentMeasure.left + x, y);
+        if (this._underline) {
+            context.beginPath();
+            context.lineWidth = Math.round(this.fontSizeInPixels * 0.05);
+            context.moveTo(this._currentMeasure.left + x, y + 3);
+            context.lineTo(this._currentMeasure.left + x + textWidth, y + 3);
+            context.stroke();
+            context.closePath();
+        }
+        if (this._lineThrough) {
+            context.beginPath();
+            context.lineWidth = Math.round(this.fontSizeInPixels * 0.05);
+            context.moveTo(this._currentMeasure.left + x, y - this.fontSizeInPixels / 3);
+            context.lineTo(this._currentMeasure.left + x + textWidth, y - this.fontSizeInPixels / 3);
+            context.stroke();
+            context.closePath();
+        }
     };
     /** @hidden */
     TextBlock.prototype._draw = function (context, invalidatedRectangle) {
@@ -12912,7 +12970,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyPropertySet", function() { return KeyPropertySet; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualKeyboard", function() { return VirtualKeyboard; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
 /* harmony import */ var _button__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./button */ "./2D/controls/button.ts");
@@ -13301,7 +13359,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector2WithInfo", function() { return Vector2WithInfo; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Matrix2D", function() { return Matrix2D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -13526,7 +13584,7 @@ var Matrix2D = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Measure", function() { return Measure; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 
 var tmpRect = [
@@ -13691,7 +13749,7 @@ var Measure = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiLinePoint", function() { return MultiLinePoint; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./valueAndUnit */ "./2D/valueAndUnit.ts");
 
@@ -13834,7 +13892,7 @@ var MultiLinePoint = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Style", function() { return Style; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./valueAndUnit */ "./2D/valueAndUnit.ts");
 
@@ -14140,7 +14198,7 @@ var ValueAndUnit = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "XmlLoader", function() { return XmlLoader; });
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -14459,7 +14517,7 @@ var XmlLoader = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AbstractButton3D", function() { return AbstractButton3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control3D */ "./3D/controls/control3D.ts");
 
@@ -14502,7 +14560,7 @@ var AbstractButton3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Button3D", function() { return Button3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _abstractButton3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./abstractButton3D */ "./3D/controls/abstractButton3D.ts");
 /* harmony import */ var _2D_advancedDynamicTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../2D/advancedDynamicTexture */ "./2D/advancedDynamicTexture.ts");
@@ -14683,7 +14741,7 @@ var Button3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container3D", function() { return Container3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control3D */ "./3D/controls/control3D.ts");
 
@@ -14840,7 +14898,7 @@ var Container3D = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Control3D", function() { return Control3D; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _vector3WithInfo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../vector3WithInfo */ "./3D/vector3WithInfo.ts");
 
@@ -15246,7 +15304,7 @@ var Control3D = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CylinderPanel", function() { return CylinderPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -15332,7 +15390,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HolographicButton", function() { return HolographicButton; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _button3D__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./button3D */ "./3D/controls/button3D.ts");
-/* harmony import */ var babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Materials/standardMaterial */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Materials/standardMaterial */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2__);
 /* harmony import */ var _materials_fluentMaterial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../materials/fluentMaterial */ "./3D/materials/fluentMaterial.ts");
 /* harmony import */ var _2D_controls_stackPanel__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../2D/controls/stackPanel */ "./2D/controls/stackPanel.ts");
@@ -15826,7 +15884,7 @@ var MeshButton3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlanePanel", function() { return PlanePanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
@@ -15881,7 +15939,7 @@ var PlanePanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScatterPanel", function() { return ScatterPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -16008,7 +16066,7 @@ var ScatterPanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpherePanel", function() { return SpherePanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -16094,7 +16152,7 @@ var SpherePanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StackPanel3D", function() { return StackPanel3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 
@@ -16219,7 +16277,7 @@ var StackPanel3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VolumeBasedPanel", function() { return VolumeBasedPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 
@@ -16410,7 +16468,7 @@ var VolumeBasedPanel = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GUI3DManager", function() { return GUI3DManager; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _controls_container3D__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controls/container3D */ "./3D/controls/container3D.ts");
 
@@ -16677,7 +16735,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FluentMaterialDefines", function() { return FluentMaterialDefines; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FluentMaterial", function() { return FluentMaterial; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _shaders_fluent_vertex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./shaders/fluent.vertex */ "./3D/materials/shaders/fluent.vertex.ts");
 /* harmony import */ var _shaders_fluent_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./shaders/fluent.fragment */ "./3D/materials/shaders/fluent.fragment.ts");
@@ -16728,10 +16786,6 @@ var FluentMaterial = /** @class */ (function (_super) {
          */
         _this.innerGlowColor = new babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["Color3"](1.0, 1.0, 1.0);
         /**
-         * Gets or sets alpha value (default is 1.0)
-         */
-        _this.alpha = 1.0;
-        /**
          * Gets or sets the albedo color (Default is Color3(0.3, 0.35, 0.4))
          */
         _this.albedoColor = new babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["Color3"](0.3, 0.35, 0.4);
@@ -16926,9 +16980,6 @@ var FluentMaterial = /** @class */ (function (_super) {
         Object(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
     ], FluentMaterial.prototype, "innerGlowColor", void 0);
     Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
-        Object(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serialize"])()
-    ], FluentMaterial.prototype, "alpha", void 0);
-    Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
         Object(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__["serializeAsColor3"])()
     ], FluentMaterial.prototype, "albedoColor", void 0);
     Object(tslib__WEBPACK_IMPORTED_MODULE_0__["__decorate"])([
@@ -17000,7 +17051,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fluentPixelShader", function() { return fluentPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'fluentPixelShader';
@@ -17022,7 +17073,7 @@ var fluentPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fluentVertexShader", function() { return fluentVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'fluentVertexShader';
@@ -17045,7 +17096,7 @@ var fluentVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector3WithInfo", function() { return Vector3WithInfo; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/perfCounter");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -17347,14 +17398,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/perfCounter":
+/***/ "babylonjs/Maths/math.vector":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_perfCounter__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__;
 
 /***/ })
 

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/gui/babylon.gui.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


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

@@ -1479,6 +1479,8 @@ declare module "babylonjs-gui/2D/controls/textBlock" {
         private _lineSpacing;
         private _outlineWidth;
         private _outlineColor;
+        private _underline;
+        private _lineThrough;
         /**
         * An event triggered after the text is changed
         */
@@ -1552,6 +1554,22 @@ declare module "babylonjs-gui/2D/controls/textBlock" {
          */
         set outlineWidth(value: number);
         /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        get underline(): boolean;
+        /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        set underline(value: boolean);
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        get lineThrough(): boolean;
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        set lineThrough(value: boolean);
+        /**
          * Gets or sets outlineColor of the text to display
          */
         get outlineColor(): string;
@@ -4125,10 +4143,6 @@ declare module "babylonjs-gui/3D/materials/fluentMaterial" {
          */
         innerGlowColor: Color3;
         /**
-         * Gets or sets alpha value (default is 1.0)
-         */
-        alpha: number;
-        /**
          * Gets or sets the albedo color (Default is Color3(0.3, 0.35, 0.4))
          */
         albedoColor: Color3;
@@ -5842,6 +5856,8 @@ declare module BABYLON.GUI {
         private _lineSpacing;
         private _outlineWidth;
         private _outlineColor;
+        private _underline;
+        private _lineThrough;
         /**
         * An event triggered after the text is changed
         */
@@ -5915,6 +5931,22 @@ declare module BABYLON.GUI {
          */
         set outlineWidth(value: number);
         /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        get underline(): boolean;
+        /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        set underline(value: boolean);
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        get lineThrough(): boolean;
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        set lineThrough(value: boolean);
+        /**
          * Gets or sets outlineColor of the text to display
          */
         get outlineColor(): string;
@@ -8296,10 +8328,6 @@ declare module BABYLON.GUI {
          */
         innerGlowColor: BABYLON.Color3;
         /**
-         * Gets or sets alpha value (default is 1.0)
-         */
-        alpha: number;
-        /**
          * Gets or sets the albedo color (Default is BABYLON.Color3(0.3, 0.35, 0.4))
          */
         albedoColor: BABYLON.Color3;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 3 - 3
dist/preview release/inspector/babylon.inspector.bundle.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 147 - 114
dist/preview release/inspector/babylon.inspector.bundle.max.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


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

@@ -1344,17 +1344,19 @@ declare module INSPECTOR {
         activeToolIndex: number;
         metadata: IMetadata;
         setMetadata(data: any): void;
+        pickerOpen: boolean;
+        setPickerOpen(open: boolean): void;
+        pickerRef: React.RefObject<HTMLDivElement>;
+        hasAlpha: boolean;
     }
     interface IToolBarState {
         toolURL: string;
-        pickerOpen: boolean;
         addOpen: boolean;
     }
     export class ToolBar extends React.Component<IToolBarProps, IToolBarState> {
-        private _addTool;
-        private _pickerRef;
         constructor(props: IToolBarProps);
         computeRGBAColor(): string;
+        shouldComponentUpdate(nextProps: IToolBarProps): boolean;
         render(): JSX.Element;
     }
 }
@@ -1375,6 +1377,18 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    export const canvasShader: {
+        path: {
+            vertexSource: string;
+            fragmentSource: string;
+        };
+        options: {
+            attributes: string[];
+            uniforms: string[];
+        };
+    };
+}
+declare module INSPECTOR {
     export interface IPixelData {
         x?: number;
         y?: number;
@@ -1418,8 +1432,11 @@ declare module INSPECTOR {
         private static PAN_SPEED;
         private static PAN_MOUSE_BUTTON;
         private static MIN_SCALE;
+        private static GRID_SCALE;
         private static MAX_SCALE;
         private static SELECT_ALL_KEY;
+        private static SAVE_KEY;
+        private static RESET_KEY;
         private static DESELECT_KEY;
         private _tool;
         private _setPixelData;
@@ -1441,7 +1458,7 @@ declare module INSPECTOR {
         private updateDisplay;
         set channels(channels: IChannel[]);
         static paintPixelsOnCanvas(pixelData: Uint8Array, canvas: HTMLCanvasElement): void;
-        grabOriginalTexture(adjustZoom?: boolean): void;
+        grabOriginalTexture(): void;
         getMouseCoordinates(pointerInfo: BABYLON.PointerInfo): BABYLON.Vector2;
         get scene(): BABYLON.Scene;
         get canvas2D(): HTMLCanvasElement;
@@ -1456,14 +1473,16 @@ declare module INSPECTOR {
         private makePlane;
         reset(): void;
         resize(newSize: BABYLON.ISize): Promise<void>;
-        setSize(size: BABYLON.ISize, adjustZoom?: boolean): void;
+        setSize(size: BABYLON.ISize): void;
         upload(file: File): void;
+        saveTexture(): void;
         dispose(): void;
     }
 }
 declare module INSPECTOR {
     interface IPropertiesBarProps {
         texture: BABYLON.BaseTexture;
+        size: BABYLON.ISize;
         saveTexture(): void;
         pixelData: IPixelData;
         face: number;
@@ -1490,6 +1509,7 @@ declare module INSPECTOR {
         constructor(props: IPropertiesBarProps);
         private pixelData;
         private getNewDimension;
+        componentWillUpdate(nextProps: IPropertiesBarProps): void;
         render(): JSX.Element;
     }
 }
@@ -1557,6 +1577,7 @@ declare module INSPECTOR {
         pixelData: IPixelData;
         face: number;
         mipLevel: number;
+        pickerOpen: boolean;
     }
     export interface IToolParameters {
         /** The visible scene in the editor. Useful for adding pointer and keyboard events. */
@@ -1632,6 +1653,7 @@ declare module INSPECTOR {
         private _UICanvas;
         private _2DCanvas;
         private _3DCanvas;
+        private _pickerRef;
         private _timer;
         private static PREVIEW_UPDATE_DELAY_MS;
         constructor(props: ITextureEditorComponentProps);
@@ -1644,6 +1666,8 @@ declare module INSPECTOR {
         getToolParameters(): IToolParameters;
         changeTool(index: number): void;
         setMetadata(newMetadata: any): void;
+        setPickerOpen(open: boolean): void;
+        onPointerDown(evt: React.PointerEvent): void;
         saveTexture(): void;
         resetTexture(): void;
         resizeTexture(width: number, height: number): void;

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

@@ -1521,17 +1521,19 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         activeToolIndex: number;
         metadata: IMetadata;
         setMetadata(data: any): void;
+        pickerOpen: boolean;
+        setPickerOpen(open: boolean): void;
+        pickerRef: React.RefObject<HTMLDivElement>;
+        hasAlpha: boolean;
     }
     interface IToolBarState {
         toolURL: string;
-        pickerOpen: boolean;
         addOpen: boolean;
     }
     export class ToolBar extends React.Component<IToolBarProps, IToolBarState> {
-        private _addTool;
-        private _pickerRef;
         constructor(props: IToolBarProps);
         computeRGBAColor(): string;
+        shouldComponentUpdate(nextProps: IToolBarProps): boolean;
         render(): JSX.Element;
     }
 }
@@ -1552,6 +1554,18 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/materials/textures/canvasShader" {
+    export const canvasShader: {
+        path: {
+            vertexSource: string;
+            fragmentSource: string;
+        };
+        options: {
+            attributes: string[];
+            uniforms: string[];
+        };
+    };
+}
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/materials/textures/textureCanvasManager" {
     import { Scene } from 'babylonjs/scene';
     import { Vector2 } from 'babylonjs/Maths/math.vector';
@@ -1605,8 +1619,11 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         private static PAN_SPEED;
         private static PAN_MOUSE_BUTTON;
         private static MIN_SCALE;
+        private static GRID_SCALE;
         private static MAX_SCALE;
         private static SELECT_ALL_KEY;
+        private static SAVE_KEY;
+        private static RESET_KEY;
         private static DESELECT_KEY;
         private _tool;
         private _setPixelData;
@@ -1628,7 +1645,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         private updateDisplay;
         set channels(channels: IChannel[]);
         static paintPixelsOnCanvas(pixelData: Uint8Array, canvas: HTMLCanvasElement): void;
-        grabOriginalTexture(adjustZoom?: boolean): void;
+        grabOriginalTexture(): void;
         getMouseCoordinates(pointerInfo: PointerInfo): Vector2;
         get scene(): Scene;
         get canvas2D(): HTMLCanvasElement;
@@ -1643,8 +1660,9 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         private makePlane;
         reset(): void;
         resize(newSize: ISize): Promise<void>;
-        setSize(size: ISize, adjustZoom?: boolean): void;
+        setSize(size: ISize): void;
         upload(file: File): void;
+        saveTexture(): void;
         dispose(): void;
     }
 }
@@ -1652,8 +1670,10 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
     import * as React from 'react';
     import { BaseTexture } from 'babylonjs/Materials/Textures/baseTexture';
     import { IPixelData } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/materials/textures/textureCanvasManager";
+    import { ISize } from 'babylonjs/Maths/math.size';
     interface IPropertiesBarProps {
         texture: BaseTexture;
+        size: ISize;
         saveTexture(): void;
         pixelData: IPixelData;
         face: number;
@@ -1680,6 +1700,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         constructor(props: IPropertiesBarProps);
         private pixelData;
         private getNewDimension;
+        componentWillUpdate(nextProps: IPropertiesBarProps): void;
         render(): JSX.Element;
     }
 }
@@ -1767,6 +1788,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         pixelData: IPixelData;
         face: number;
         mipLevel: number;
+        pickerOpen: boolean;
     }
     export interface IToolParameters {
         /** The visible scene in the editor. Useful for adding pointer and keyboard events. */
@@ -1842,6 +1864,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         private _UICanvas;
         private _2DCanvas;
         private _3DCanvas;
+        private _pickerRef;
         private _timer;
         private static PREVIEW_UPDATE_DELAY_MS;
         constructor(props: ITextureEditorComponentProps);
@@ -1854,6 +1877,8 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         getToolParameters(): IToolParameters;
         changeTool(index: number): void;
         setMetadata(newMetadata: any): void;
+        setPickerOpen(open: boolean): void;
+        onPointerDown(evt: React.PointerEvent): void;
         saveTexture(): void;
         resetTexture(): void;
         resizeTexture(width: number, height: number): void;
@@ -5505,17 +5530,19 @@ declare module INSPECTOR {
         activeToolIndex: number;
         metadata: IMetadata;
         setMetadata(data: any): void;
+        pickerOpen: boolean;
+        setPickerOpen(open: boolean): void;
+        pickerRef: React.RefObject<HTMLDivElement>;
+        hasAlpha: boolean;
     }
     interface IToolBarState {
         toolURL: string;
-        pickerOpen: boolean;
         addOpen: boolean;
     }
     export class ToolBar extends React.Component<IToolBarProps, IToolBarState> {
-        private _addTool;
-        private _pickerRef;
         constructor(props: IToolBarProps);
         computeRGBAColor(): string;
+        shouldComponentUpdate(nextProps: IToolBarProps): boolean;
         render(): JSX.Element;
     }
 }
@@ -5536,6 +5563,18 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    export const canvasShader: {
+        path: {
+            vertexSource: string;
+            fragmentSource: string;
+        };
+        options: {
+            attributes: string[];
+            uniforms: string[];
+        };
+    };
+}
+declare module INSPECTOR {
     export interface IPixelData {
         x?: number;
         y?: number;
@@ -5579,8 +5618,11 @@ declare module INSPECTOR {
         private static PAN_SPEED;
         private static PAN_MOUSE_BUTTON;
         private static MIN_SCALE;
+        private static GRID_SCALE;
         private static MAX_SCALE;
         private static SELECT_ALL_KEY;
+        private static SAVE_KEY;
+        private static RESET_KEY;
         private static DESELECT_KEY;
         private _tool;
         private _setPixelData;
@@ -5602,7 +5644,7 @@ declare module INSPECTOR {
         private updateDisplay;
         set channels(channels: IChannel[]);
         static paintPixelsOnCanvas(pixelData: Uint8Array, canvas: HTMLCanvasElement): void;
-        grabOriginalTexture(adjustZoom?: boolean): void;
+        grabOriginalTexture(): void;
         getMouseCoordinates(pointerInfo: BABYLON.PointerInfo): BABYLON.Vector2;
         get scene(): BABYLON.Scene;
         get canvas2D(): HTMLCanvasElement;
@@ -5617,14 +5659,16 @@ declare module INSPECTOR {
         private makePlane;
         reset(): void;
         resize(newSize: BABYLON.ISize): Promise<void>;
-        setSize(size: BABYLON.ISize, adjustZoom?: boolean): void;
+        setSize(size: BABYLON.ISize): void;
         upload(file: File): void;
+        saveTexture(): void;
         dispose(): void;
     }
 }
 declare module INSPECTOR {
     interface IPropertiesBarProps {
         texture: BABYLON.BaseTexture;
+        size: BABYLON.ISize;
         saveTexture(): void;
         pixelData: IPixelData;
         face: number;
@@ -5651,6 +5695,7 @@ declare module INSPECTOR {
         constructor(props: IPropertiesBarProps);
         private pixelData;
         private getNewDimension;
+        componentWillUpdate(nextProps: IPropertiesBarProps): void;
         render(): JSX.Element;
     }
 }
@@ -5718,6 +5763,7 @@ declare module INSPECTOR {
         pixelData: IPixelData;
         face: number;
         mipLevel: number;
+        pickerOpen: boolean;
     }
     export interface IToolParameters {
         /** The visible scene in the editor. Useful for adding pointer and keyboard events. */
@@ -5793,6 +5839,7 @@ declare module INSPECTOR {
         private _UICanvas;
         private _2DCanvas;
         private _3DCanvas;
+        private _pickerRef;
         private _timer;
         private static PREVIEW_UPDATE_DELAY_MS;
         constructor(props: ITextureEditorComponentProps);
@@ -5805,6 +5852,8 @@ declare module INSPECTOR {
         getToolParameters(): IToolParameters;
         changeTool(index: number): void;
         setMetadata(newMetadata: any): void;
+        setPickerOpen(open: boolean): void;
+        onPointerDown(evt: React.PointerEvent): void;
         saveTexture(): void;
         resetTexture(): void;
         resizeTexture(width: number, height: number): void;

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 40 - 39
dist/preview release/loaders/babylon.glTF2FileLoader.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 40 - 39
dist/preview release/loaders/babylon.glTFFileLoader.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylon.stlFileLoader.min.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 40 - 39
dist/preview release/loaders/babylonjs.loaders.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


+ 36 - 0
dist/preview release/nodeEditor/babylon.nodeEditor.d.ts

@@ -1267,6 +1267,39 @@ declare module NODEEDITOR {
     }
 }
 declare module NODEEDITOR {
+    export interface IDraggableLineWithButtonComponent {
+        data: string;
+        tooltip: string;
+        iconImage: any;
+        onIconClick: (value: string) => void;
+        iconTitle: string;
+    }
+    export class DraggableLineWithButtonComponent extends React.Component<IDraggableLineWithButtonComponent> {
+        constructor(props: IDraggableLineWithButtonComponent);
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    interface ILineWithFileButtonComponentProps {
+        title: string;
+        closed?: boolean;
+        label: string;
+        iconImage: any;
+        onIconClick: (file: File) => void;
+        accept: string;
+        uploadName?: string;
+    }
+    export class LineWithFileButtonComponent extends React.Component<ILineWithFileButtonComponentProps, {
+        isExpanded: boolean;
+    }> {
+        private uploadRef;
+        constructor(props: ILineWithFileButtonComponentProps);
+        onChange(evt: any): void;
+        switchExpandedState(): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
     interface INodeListComponentProps {
         globalState: GlobalState;
     }
@@ -1275,9 +1308,12 @@ declare module NODEEDITOR {
     }> {
         private _onResetRequiredObserver;
         private static _Tooltips;
+        private _customFrameList;
         constructor(props: INodeListComponentProps);
         componentWillUnmount(): void;
         filterContent(filter: string): void;
+        loadCustomFrame(file: File): void;
+        removeItem(value: string): void;
         render(): JSX.Element;
     }
 }

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 6 - 6
dist/preview release/nodeEditor/babylon.nodeEditor.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 212 - 6
dist/preview release/nodeEditor/babylon.nodeEditor.max.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


+ 74 - 0
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts

@@ -1544,6 +1544,41 @@ declare module "babylonjs-node-editor/sharedComponents/draggableLineComponent" {
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-node-editor/sharedComponents/draggableLineWithButtonComponent" {
+    import * as React from "react";
+    export interface IDraggableLineWithButtonComponent {
+        data: string;
+        tooltip: string;
+        iconImage: any;
+        onIconClick: (value: string) => void;
+        iconTitle: string;
+    }
+    export class DraggableLineWithButtonComponent extends React.Component<IDraggableLineWithButtonComponent> {
+        constructor(props: IDraggableLineWithButtonComponent);
+        render(): JSX.Element;
+    }
+}
+declare module "babylonjs-node-editor/sharedComponents/lineWithFileButtonComponent" {
+    import * as React from "react";
+    interface ILineWithFileButtonComponentProps {
+        title: string;
+        closed?: boolean;
+        label: string;
+        iconImage: any;
+        onIconClick: (file: File) => void;
+        accept: string;
+        uploadName?: string;
+    }
+    export class LineWithFileButtonComponent extends React.Component<ILineWithFileButtonComponentProps, {
+        isExpanded: boolean;
+    }> {
+        private uploadRef;
+        constructor(props: ILineWithFileButtonComponentProps);
+        onChange(evt: any): void;
+        switchExpandedState(): void;
+        render(): JSX.Element;
+    }
+}
 declare module "babylonjs-node-editor/components/nodeList/nodeListComponent" {
     import * as React from "react";
     import { GlobalState } from "babylonjs-node-editor/globalState";
@@ -1555,9 +1590,12 @@ declare module "babylonjs-node-editor/components/nodeList/nodeListComponent" {
     }> {
         private _onResetRequiredObserver;
         private static _Tooltips;
+        private _customFrameList;
         constructor(props: INodeListComponentProps);
         componentWillUnmount(): void;
         filterContent(filter: string): void;
+        loadCustomFrame(file: File): void;
+        removeItem(value: string): void;
         render(): JSX.Element;
     }
 }
@@ -3131,6 +3169,39 @@ declare module NODEEDITOR {
     }
 }
 declare module NODEEDITOR {
+    export interface IDraggableLineWithButtonComponent {
+        data: string;
+        tooltip: string;
+        iconImage: any;
+        onIconClick: (value: string) => void;
+        iconTitle: string;
+    }
+    export class DraggableLineWithButtonComponent extends React.Component<IDraggableLineWithButtonComponent> {
+        constructor(props: IDraggableLineWithButtonComponent);
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
+    interface ILineWithFileButtonComponentProps {
+        title: string;
+        closed?: boolean;
+        label: string;
+        iconImage: any;
+        onIconClick: (file: File) => void;
+        accept: string;
+        uploadName?: string;
+    }
+    export class LineWithFileButtonComponent extends React.Component<ILineWithFileButtonComponentProps, {
+        isExpanded: boolean;
+    }> {
+        private uploadRef;
+        constructor(props: ILineWithFileButtonComponentProps);
+        onChange(evt: any): void;
+        switchExpandedState(): void;
+        render(): JSX.Element;
+    }
+}
+declare module NODEEDITOR {
     interface INodeListComponentProps {
         globalState: GlobalState;
     }
@@ -3139,9 +3210,12 @@ declare module NODEEDITOR {
     }> {
         private _onResetRequiredObserver;
         private static _Tooltips;
+        private _customFrameList;
         constructor(props: INodeListComponentProps);
         componentWillUnmount(): void;
         filterContent(filter: string): void;
+        loadCustomFrame(file: File): void;
+        removeItem(value: string): void;
         render(): JSX.Element;
     }
 }

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

@@ -1 +1 @@
-{"thinEngineOnly":117231,"engineOnly":153671,"sceneOnly":517938,"minGridMaterial":656459,"minStandardMaterial":805884}
+{"thinEngineOnly":117231,"engineOnly":153671,"sceneOnly":518525,"minGridMaterial":657905,"minStandardMaterial":807726}

+ 402 - 30
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -429,7 +429,7 @@ var KHR_lights_punctual = /** @class */ (function () {
     }
     /** @hidden */
     KHR_lights_punctual.prototype.dispose = function () {
-        delete this._lights;
+        this._lights = null;
     };
     Object.defineProperty(KHR_lights_punctual.prototype, "wasUsed", {
         /** @hidden */
@@ -952,6 +952,8 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
+
 /**
  * @hidden
  * Enum for handling in tangent and out tangent.
@@ -1045,6 +1047,11 @@ var _GLTFAnimation = /** @class */ (function () {
                 animationChannelTargetPath = "rotation" /* ROTATION */;
                 break;
             }
+            case 'influence': {
+                dataAccessorType = "SCALAR" /* SCALAR */;
+                animationChannelTargetPath = "weights" /* WEIGHTS */;
+                break;
+            }
             default: {
                 babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Tools"].Error("Unsupported animatable property " + property[0]);
             }
@@ -1094,8 +1101,63 @@ var _GLTFAnimation = /** @class */ (function () {
         }
     };
     /**
+ * @ignore
+ * Create individual morph animations from the mesh's morph target animation tracks
+ * @param babylonNode
+ * @param runtimeGLTFAnimation
+ * @param idleGLTFAnimations
+ * @param nodeMap
+ * @param nodes
+ * @param binaryWriter
+ * @param bufferViews
+ * @param accessors
+ * @param convertToRightHandedSystem
+ * @param animationSampleRate
+ */
+    _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargets = function (babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
+        var glTFAnimation;
+        if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Mesh"]) {
+            var morphTargetManager = babylonNode.morphTargetManager;
+            if (morphTargetManager) {
+                for (var i = 0; i < morphTargetManager.numTargets; ++i) {
+                    var morphTarget = morphTargetManager.getTarget(i);
+                    for (var j = 0; j < morphTarget.animations.length; ++j) {
+                        var animation = morphTarget.animations[j];
+                        var combinedAnimation = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"]("" + animation.name, "influence", animation.framePerSecond, animation.dataType, animation.loopMode, animation.enableBlending);
+                        var combinedAnimationKeys = [];
+                        var animationKeys = animation.getKeys();
+                        for (var k = 0; k < animationKeys.length; ++k) {
+                            var animationKey = animationKeys[k];
+                            for (var l = 0; l < morphTargetManager.numTargets; ++l) {
+                                if (l == i) {
+                                    combinedAnimationKeys.push(animationKey);
+                                }
+                                else {
+                                    combinedAnimationKeys.push({ frame: animationKey.frame, value: morphTargetManager.getTarget(l).influence });
+                                }
+                            }
+                        }
+                        combinedAnimation.setKeys(combinedAnimationKeys);
+                        var animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimation);
+                        if (animationInfo) {
+                            glTFAnimation = {
+                                name: combinedAnimation.name,
+                                samplers: [],
+                                channels: []
+                            };
+                            _GLTFAnimation.AddAnimation("" + animation.name, animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation, babylonNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate, morphTargetManager.numTargets);
+                            if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {
+                                idleGLTFAnimations.push(glTFAnimation);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    };
+    /**
      * @ignore
-     * Create node animations from the animation groups
+     * Create node and morph animations from the animation groups
      * @param babylonScene
      * @param glTFAnimations
      * @param nodeMap
@@ -1107,18 +1169,22 @@ var _GLTFAnimation = /** @class */ (function () {
      * @param animationSampleRate
      */
     _GLTFAnimation._CreateNodeAnimationFromAnimationGroups = function (babylonScene, glTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystemMap, animationSampleRate) {
+        var _a;
         var glTFAnimation;
         if (babylonScene.animationGroups) {
             var animationGroups = babylonScene.animationGroups;
-            for (var _i = 0, animationGroups_1 = animationGroups; _i < animationGroups_1.length; _i++) {
-                var animationGroup = animationGroups_1[_i];
+            var _loop_1 = function (animationGroup) {
+                var morphAnimations = new Map();
+                var sampleAnimations = new Map();
+                var morphAnimationMeshes = new Set();
+                var animationGroupFrameDiff = animationGroup.to - animationGroup.from;
                 glTFAnimation = {
                     name: animationGroup.name,
                     channels: [],
                     samplers: []
                 };
-                for (var _a = 0, _b = animationGroup.targetedAnimations; _a < _b.length; _a++) {
-                    var targetAnimation = _b[_a];
+                var _loop_2 = function (i) {
+                    var targetAnimation = animationGroup.targetedAnimations[i];
                     var target = targetAnimation.target;
                     var animation = targetAnimation.animation;
                     if (target instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TransformNode"] || target.length === 1 && target[0] instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]) {
@@ -1129,15 +1195,87 @@ var _GLTFAnimation = /** @class */ (function () {
                             _GLTFAnimation.AddAnimation("" + animation.name, glTFAnimation, babylonTransformNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate);
                         }
                     }
+                    else if (target instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["MorphTarget"] || target.length === 1 && target[0] instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["MorphTarget"]) {
+                        var animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);
+                        if (animationInfo) {
+                            var babylonMorphTarget_1 = target instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["MorphTarget"] ? target : target[0];
+                            if (babylonMorphTarget_1) {
+                                var babylonMorphTargetManager_1 = babylonScene.morphTargetManagers.find(function (morphTargetManager) {
+                                    for (var j = 0; j < morphTargetManager.numTargets; ++j) {
+                                        if (morphTargetManager.getTarget(j) === babylonMorphTarget_1) {
+                                            return true;
+                                        }
+                                    }
+                                    return false;
+                                });
+                                if (babylonMorphTargetManager_1) {
+                                    var babylonMesh = babylonScene.meshes.find(function (mesh) {
+                                        return mesh.morphTargetManager === babylonMorphTargetManager_1;
+                                    });
+                                    if (babylonMesh) {
+                                        if (!morphAnimations.has(babylonMesh)) {
+                                            morphAnimations.set(babylonMesh, new Map());
+                                        }
+                                        (_a = morphAnimations.get(babylonMesh)) === null || _a === void 0 ? void 0 : _a.set(babylonMorphTarget_1, animation);
+                                        morphAnimationMeshes.add(babylonMesh);
+                                        sampleAnimations.set(babylonMesh, animation);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                };
+                for (var i = 0; i < animationGroup.targetedAnimations.length; ++i) {
+                    _loop_2(i);
                 }
+                morphAnimationMeshes.forEach(function (mesh) {
+                    // for each mesh that we want to export a Morph target animation track for...
+                    var morphTargetManager = mesh.morphTargetManager;
+                    var combinedAnimationGroup = null;
+                    var animationKeys = [];
+                    var sampleAnimation = sampleAnimations.get(mesh);
+                    var numAnimationKeys = sampleAnimation.getKeys().length;
+                    // for each frame of this mesh's animation group track
+                    for (var i = 0; i < numAnimationKeys; ++i) {
+                        // construct a new Animation track by interlacing the frames of each morph target animation track
+                        if (morphTargetManager) {
+                            for (var j = 0; j < morphTargetManager.numTargets; ++j) {
+                                var morphTarget = morphTargetManager.getTarget(j);
+                                var animationsByMorphTarget = morphAnimations.get(mesh);
+                                if (animationsByMorphTarget) {
+                                    var morphTargetAnimation = animationsByMorphTarget.get(morphTarget);
+                                    if (morphTargetAnimation) {
+                                        if (!combinedAnimationGroup) {
+                                            combinedAnimationGroup = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"](animationGroup.name + "_" + mesh.name + "_MorphWeightAnimation", "influence", morphTargetAnimation.framePerSecond, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONTYPE_FLOAT, morphTargetAnimation.loopMode, morphTargetAnimation.enableBlending);
+                                        }
+                                        animationKeys.push(morphTargetAnimation.getKeys()[i]);
+                                    }
+                                    else {
+                                        animationKeys.push({ frame: animationGroup.from + (animationGroupFrameDiff / numAnimationKeys) * i, value: morphTarget.influence });
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    combinedAnimationGroup.setKeys(animationKeys);
+                    var animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimationGroup);
+                    if (animationInfo) {
+                        _GLTFAnimation.AddAnimation(animationGroup.name + "_" + mesh.name + "_MorphWeightAnimation", glTFAnimation, mesh, combinedAnimationGroup, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, false, animationInfo.useQuaternion, animationSampleRate, morphTargetManager === null || morphTargetManager === void 0 ? void 0 : morphTargetManager.numTargets);
+                    }
+                });
                 if (glTFAnimation.channels.length && glTFAnimation.samplers.length) {
                     glTFAnimations.push(glTFAnimation);
                 }
+            };
+            for (var _i = 0, animationGroups_1 = animationGroups; _i < animationGroups_1.length; _i++) {
+                var animationGroup = animationGroups_1[_i];
+                _loop_1(animationGroup);
             }
         }
     };
-    _GLTFAnimation.AddAnimation = function (name, glTFAnimation, babylonTransformNode, animation, dataAccessorType, animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, useQuaternion, animationSampleRate) {
-        var animationData = _GLTFAnimation._CreateNodeAnimation(babylonTransformNode, animation, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion, animationSampleRate);
+    _GLTFAnimation.AddAnimation = function (name, glTFAnimation, babylonTransformNode, animation, dataAccessorType, animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, useQuaternion, animationSampleRate, morphAnimationChannels) {
+        var animationData;
+        animationData = _GLTFAnimation._CreateNodeAnimation(babylonTransformNode, animation, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion, animationSampleRate);
         var bufferView;
         var accessor;
         var keyframeAccessorIndex;
@@ -1146,6 +1284,19 @@ var _GLTFAnimation = /** @class */ (function () {
         var animationSampler;
         var animationChannel;
         if (animationData) {
+            if (morphAnimationChannels) {
+                var index = 0;
+                var currentInput = 0;
+                var newInputs = [];
+                while (animationData.inputs.length > 0) {
+                    currentInput = animationData.inputs.shift();
+                    if (index % morphAnimationChannels == 0) {
+                        newInputs.push(currentInput);
+                    }
+                    index++;
+                }
+                animationData.inputs = newInputs;
+            }
             var nodeIndex = nodeMap[babylonTransformNode.uniqueId];
             // Creates buffer view and accessor for key frames.
             var byteLength = animationData.inputs.length * 4;
@@ -1159,7 +1310,7 @@ var _GLTFAnimation = /** @class */ (function () {
             keyframeAccessorIndex = accessors.length - 1;
             // create bufferview and accessor for keyed values.
             outputLength = animationData.outputs.length;
-            byteLength = dataAccessorType === "VEC3" /* VEC3 */ ? animationData.outputs.length * 12 : animationData.outputs.length * 16;
+            byteLength = _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetDataAccessorElementCount(dataAccessorType) * 4 * animationData.outputs.length;
             // check for in and out tangents
             bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, name + "  data view");
             bufferViews.push(bufferView);
@@ -1300,7 +1451,7 @@ var _GLTFAnimation = /** @class */ (function () {
         var animationType = animation.dataType;
         var cacheValue;
         inputs.push(time);
-        if (typeof value === "number") {
+        if (typeof value === "number" && babylonTransformNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]) {
             value = this._ConvertFactorToVector3OrQuaternion(value, babylonTransformNode, animation, animationType, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion);
         }
         if (value) {
@@ -1320,7 +1471,10 @@ var _GLTFAnimation = /** @class */ (function () {
                 }
                 outputs.push(quaternionCache.asArray());
             }
-            else {
+            else if (animationChannelTargetPath === "weights" /* WEIGHTS */) {
+                outputs.push([value]);
+            }
+            else { // scaling and position animation
                 cacheValue = value;
                 if (convertToRightHandedSystem && (animationChannelTargetPath !== "scale" /* SCALE */)) {
                     _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(cacheValue);
@@ -1441,29 +1595,34 @@ var _GLTFAnimation = /** @class */ (function () {
             }
             outputs.push(value); // scale  vector.
         }
-        else if (animationType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONTYPE_FLOAT) { // handles single component x, y, z or w component animation by using a base property and animating over a component.
-            newPositionRotationOrScale = this._ConvertFactorToVector3OrQuaternion(keyFrame.value, babylonTransformNode, animation, animationType, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion);
-            if (newPositionRotationOrScale) {
-                if (animationChannelTargetPath === "rotation" /* ROTATION */) {
-                    var posRotScale = useQuaternion ? newPositionRotationOrScale : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize();
-                    if (convertToRightHandedSystem) {
-                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(posRotScale);
-                        if (!babylonTransformNode.parent) {
-                            posRotScale = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArray([0, 1, 0, 0]).multiply(posRotScale);
+        else if (animationType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONTYPE_FLOAT) {
+            if (animationChannelTargetPath === "weights" /* WEIGHTS */) {
+                outputs.push([keyFrame.value]);
+            }
+            else { // handles single component x, y, z or w component animation by using a base property and animating over a component.
+                newPositionRotationOrScale = this._ConvertFactorToVector3OrQuaternion(keyFrame.value, babylonTransformNode, animation, animationType, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion);
+                if (newPositionRotationOrScale) {
+                    if (animationChannelTargetPath === "rotation" /* ROTATION */) {
+                        var posRotScale = useQuaternion ? newPositionRotationOrScale : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize();
+                        if (convertToRightHandedSystem) {
+                            _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(posRotScale);
+                            if (!babylonTransformNode.parent) {
+                                posRotScale = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArray([0, 1, 0, 0]).multiply(posRotScale);
+                            }
                         }
+                        outputs.push(posRotScale.asArray());
                     }
-                    outputs.push(posRotScale.asArray());
-                }
-                else if (animationChannelTargetPath === "translation" /* TRANSLATION */) {
-                    if (convertToRightHandedSystem) {
-                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(newPositionRotationOrScale);
-                        if (!babylonTransformNode.parent) {
-                            newPositionRotationOrScale.x *= -1;
-                            newPositionRotationOrScale.z *= -1;
+                    else if (animationChannelTargetPath === "translation" /* TRANSLATION */) {
+                        if (convertToRightHandedSystem) {
+                            _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(newPositionRotationOrScale);
+                            if (!babylonTransformNode.parent) {
+                                newPositionRotationOrScale.x *= -1;
+                                newPositionRotationOrScale.z *= -1;
+                            }
                         }
                     }
+                    outputs.push(newPositionRotationOrScale.asArray());
                 }
-                outputs.push(newPositionRotationOrScale.asArray());
             }
         }
         else if (animationType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONTYPE_QUATERNION) {
@@ -1567,6 +1726,14 @@ var _GLTFAnimation = /** @class */ (function () {
                     tangent = [0, 0, 0, 0];
                 }
             }
+            else if (animationChannelTargetPath === "weights" /* WEIGHTS */) {
+                if (tangentValue) {
+                    tangent = [tangentValue];
+                }
+                else {
+                    tangent = [0];
+                }
+            }
             else {
                 if (tangentValue) {
                     tangent = tangentValue.asArray();
@@ -2313,6 +2480,103 @@ var _Exporter = /** @class */ (function () {
         }
     };
     /**
+     * Writes mesh attribute data to a data buffer
+     * Returns the bytelength of the data
+     * @param vertexBufferKind Indicates what kind of vertex data is being passed in
+     * @param meshAttributeArray Array containing the attribute data
+     * @param byteStride Specifies the space between data
+     * @param binaryWriter The buffer to write the binary data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
+     */
+    _Exporter.prototype.writeMorphTargetAttributeData = function (vertexBufferKind, attributeComponentKind, meshPrimitive, morphTarget, meshAttributeArray, morphTargetAttributeArray, stride, binaryWriter, convertToRightHandedSystem, minMax) {
+        var vertexAttributes = [];
+        var index;
+        var difference = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"]();
+        var difference4 = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"](0, 0, 0, 0);
+        switch (vertexBufferKind) {
+            case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind: {
+                for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
+                    index = meshPrimitive.indexStart + k * stride;
+                    var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(meshAttributeArray, index);
+                    var morphData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(morphTargetAttributeArray, index);
+                    difference = morphData.subtractToRef(vertexData, difference);
+                    if (convertToRightHandedSystem) {
+                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(difference);
+                    }
+                    if (minMax) {
+                        minMax.min.copyFromFloats(Math.min(difference.x, minMax.min.x), Math.min(difference.y, minMax.min.y), Math.min(difference.z, minMax.min.z));
+                        minMax.max.copyFromFloats(Math.max(difference.x, minMax.max.x), Math.max(difference.y, minMax.max.y), Math.max(difference.z, minMax.max.z));
+                    }
+                    vertexAttributes.push(difference.asArray());
+                }
+                break;
+            }
+            case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind: {
+                for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
+                    index = meshPrimitive.indexStart + k * stride;
+                    var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(meshAttributeArray, index);
+                    vertexData.normalize();
+                    var morphData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(morphTargetAttributeArray, index);
+                    morphData.normalize();
+                    difference = morphData.subtractToRef(vertexData, difference);
+                    if (convertToRightHandedSystem) {
+                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(difference);
+                    }
+                    vertexAttributes.push(difference.asArray());
+                }
+                break;
+            }
+            case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind: {
+                for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
+                    index = meshPrimitive.indexStart + k * (stride + 1);
+                    var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"].FromArray(meshAttributeArray, index);
+                    _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._NormalizeTangentFromRef(vertexData);
+                    var morphData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"].FromArray(morphTargetAttributeArray, index);
+                    _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._NormalizeTangentFromRef(morphData);
+                    difference4 = morphData.subtractToRef(vertexData, difference4);
+                    if (convertToRightHandedSystem) {
+                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedVector4FromRef(difference4);
+                    }
+                    vertexAttributes.push([difference4.x, difference4.y, difference4.z]);
+                }
+                break;
+            }
+            default: {
+                babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind);
+                vertexAttributes = [];
+            }
+        }
+        var writeBinaryFunc;
+        switch (attributeComponentKind) {
+            case 5121 /* UNSIGNED_BYTE */: {
+                writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);
+                break;
+            }
+            case 5123 /* UNSIGNED_SHORT */: {
+                writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);
+                break;
+            }
+            case 5125 /* UNSIGNED_INT */: {
+                writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);
+            }
+            case 5126 /* FLOAT */: {
+                writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);
+                break;
+            }
+            default: {
+                babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Unsupported Attribute Component kind: " + attributeComponentKind);
+                return;
+            }
+        }
+        for (var _i = 0, vertexAttributes_2 = vertexAttributes; _i < vertexAttributes_2.length; _i++) {
+            var vertexAttribute = vertexAttributes_2[_i];
+            for (var _a = 0, vertexAttribute_2 = vertexAttribute; _a < vertexAttribute_2.length; _a++) {
+                var component = vertexAttribute_2[_a];
+                writeBinaryFunc(component);
+            }
+        }
+    };
+    /**
      * Generates glTF json data
      * @param shouldUseGlb Indicates whether the json should be written for a glb file
      * @param glTFPrefix Text to use when prefixing a glTF file
@@ -2584,6 +2848,67 @@ var _Exporter = /** @class */ (function () {
         }
     };
     /**
+ * Creates a bufferview based on the vertices type for the Babylon mesh
+ * @param babylonSubMesh The Babylon submesh that the morph target is applied to
+ * @param babylonMorphTarget the morph target to be exported
+ * @param binaryWriter The buffer to write the bufferview data to
+ * @param convertToRightHandedSystem Converts the values to right-handed
+ */
+    _Exporter.prototype.setMorphTargetAttributes = function (babylonSubMesh, meshPrimitive, babylonMorphTarget, binaryWriter, convertToRightHandedSystem) {
+        if (babylonMorphTarget) {
+            if (!meshPrimitive.targets) {
+                meshPrimitive.targets = [];
+            }
+            var target = {};
+            if (babylonMorphTarget.hasNormals) {
+                var vertexNormals = babylonSubMesh.getMesh().getVerticesData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind);
+                var morphNormals = babylonMorphTarget.getNormals();
+                var count = babylonSubMesh.verticesCount;
+                var byteStride = 12; // 3 x 4 byte floats
+                var byteLength = count * byteStride;
+                var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
+                this._bufferViews.push(bufferView);
+                var bufferViewIndex = this._bufferViews.length - 1;
+                var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "NORMAL", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
+                this._accessors.push(accessor);
+                target.NORMAL = this._accessors.length - 1;
+                this.writeMorphTargetAttributeData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexNormals, morphNormals, byteStride / 4, binaryWriter, convertToRightHandedSystem);
+            }
+            if (babylonMorphTarget.hasPositions) {
+                var vertexPositions = babylonSubMesh.getMesh().getVerticesData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind);
+                var morphPositions = babylonMorphTarget.getPositions();
+                var count = babylonSubMesh.verticesCount;
+                var byteStride = 12; // 3 x 4 byte floats
+                var byteLength = count * byteStride;
+                var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_POSITION");
+                this._bufferViews.push(bufferView);
+                var bufferViewIndex = this._bufferViews.length - 1;
+                var minMax = { min: new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](Infinity, Infinity, Infinity), max: new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](-Infinity, -Infinity, -Infinity) };
+                var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "POSITION", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
+                this._accessors.push(accessor);
+                target.POSITION = this._accessors.length - 1;
+                this.writeMorphTargetAttributeData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexPositions, morphPositions, byteStride / 4, binaryWriter, convertToRightHandedSystem, minMax);
+                accessor.min = minMax.min.asArray();
+                accessor.max = minMax.max.asArray();
+            }
+            if (babylonMorphTarget.hasTangents) {
+                var vertexTangents = babylonSubMesh.getMesh().getVerticesData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind);
+                var morphTangents = babylonMorphTarget.getTangents();
+                var count = babylonSubMesh.verticesCount;
+                var byteStride = 12; // 3 x 4 byte floats
+                var byteLength = count * byteStride;
+                var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
+                this._bufferViews.push(bufferView);
+                var bufferViewIndex = this._bufferViews.length - 1;
+                var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "TANGENT", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
+                this._accessors.push(accessor);
+                target.TANGENT = this._accessors.length - 1;
+                this.writeMorphTargetAttributeData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexTangents, morphTangents, byteStride / 4, binaryWriter, convertToRightHandedSystem);
+            }
+            meshPrimitive.targets.push(target);
+        }
+    };
+    /**
      * The primitive mode of the Babylon mesh
      * @param babylonMesh The BabylonJS mesh
      */
@@ -2721,6 +3046,7 @@ var _Exporter = /** @class */ (function () {
             var indexBufferViewIndex = null;
             var primitiveMode = this.getMeshPrimitiveMode(bufferMesh);
             var vertexAttributeBufferViews = {};
+            var morphTargetManager = bufferMesh.morphTargetManager;
             // For each BabylonMesh, create bufferviews for each 'kind'
             for (var _i = 0, attributeData_1 = attributeData; _i < attributeData_1.length; _i++) {
                 var attribute = attributeData_1[_i];
@@ -2846,6 +3172,13 @@ var _Exporter = /** @class */ (function () {
                         }
                         meshPrimitive.material = materialIndex;
                     }
+                    if (morphTargetManager) {
+                        var target = void 0;
+                        for (var i = 0; i < morphTargetManager.numTargets; ++i) {
+                            target = morphTargetManager.getTarget(i);
+                            this.setMorphTargetAttributes(submesh, meshPrimitive, target, binaryWriter, convertToRightHandedSystem);
+                        }
+                    }
                     mesh.primitives.push(meshPrimitive);
                     var promise = this._extensionsPostExportMeshPrimitiveAsync("postExport", meshPrimitive, submesh, binaryWriter);
                     if (promise) {
@@ -3032,6 +3365,7 @@ var _Exporter = /** @class */ (function () {
                                 nodeMap[babylonNode.uniqueId] = nodeIndex;
                                 if (!babylonScene.animationGroups.length && babylonNode.animations.length) {
                                     _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
+                                    _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateMorphTargetAnimationFromMorphTargets(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
                                 }
                             });
                         }
@@ -3083,6 +3417,15 @@ var _Exporter = /** @class */ (function () {
             if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TransformNode"]) {
                 // Set transformation
                 _this.setNodeTransformation(node, babylonNode, convertToRightHandedSystem);
+                if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Mesh"]) {
+                    var morphTargetManager = babylonNode.morphTargetManager;
+                    if (morphTargetManager && morphTargetManager.numTargets > 0) {
+                        mesh.weights = [];
+                        for (var i = 0; i < morphTargetManager.numTargets; ++i) {
+                            mesh.weights.push(morphTargetManager.getTarget(i).influence);
+                        }
+                    }
+                }
                 return _this.setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter, convertToRightHandedSystem).then(function () {
                     if (mesh.primitives.length) {
                         _this._meshes.push(mesh);
@@ -3803,7 +4146,7 @@ var _GLTFMaterialExporter = /** @class */ (function () {
                             else {
                                 reject("gltfMaterialExporter: Failed to get blob from image canvas!");
                             }
-                        });
+                        }, mimeType);
                     }
                 }
                 else {
@@ -4399,6 +4742,17 @@ var _GLTFMaterialExporter = /** @class */ (function () {
                     samplerIndex_1 = foundSamplerIndex;
                 }
                 var size = babylonTexture.getSize();
+                // Preserve texture mime type if defined
+                if (babylonTexture.mimeType) {
+                    switch (babylonTexture.mimeType) {
+                        case "image/jpeg":
+                            mimeType = "image/jpeg" /* JPEG */;
+                            break;
+                        case "image/png":
+                            mimeType = "image/png" /* PNG */;
+                            break;
+                    }
+                }
                 return _this._createBase64FromCanvasAsync(pixels, size.width, size.height, mimeType).then(function (base64Data) {
                     var textureInfo = _this._getTextureInfoFromBase64(base64Data, babylonTexture.name.replace(/\.\/|\/|\.\\|\\/g, "_"), mimeType, babylonTexture.coordinatesIndex, samplerIndex_1);
                     if (textureInfo) {
@@ -4764,6 +5118,24 @@ var _GLTFUtilities = /** @class */ (function () {
         var m = matrix.m;
         babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].FromValuesToRef(m[0], m[1], -m[2], m[3], m[4], m[5], -m[6], m[7], -m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15], matrix);
     };
+    _GLTFUtilities._GetDataAccessorElementCount = function (accessorType) {
+        switch (accessorType) {
+            case "MAT2" /* MAT2 */:
+                return 4;
+            case "MAT3" /* MAT3 */:
+                return 9;
+            case "MAT4" /* MAT4 */:
+                return 16;
+            case "SCALAR" /* SCALAR */:
+                return 1;
+            case "VEC2" /* VEC2 */:
+                return 2;
+            case "VEC3" /* VEC3 */:
+                return 3;
+            case "VEC4" /* VEC4 */:
+                return 4;
+        }
+    };
     return _GLTFUtilities;
 }());
 

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 38 - 2
dist/preview release/serializers/babylonjs.serializers.d.ts

@@ -499,6 +499,7 @@ declare module BABYLON.GLTF2.Exporter {
         static _GetRightHandedQuaternionArrayFromRef(quaternion: number[]): void;
         static _NormalizeTangentFromRef(tangent: Vector4): void;
         static _GetRightHandedMatrixFromRef(matrix: Matrix): void;
+        static _GetDataAccessorElementCount(accessorType: AccessorType): 1 | 3 | 2 | 4 | 9 | 16;
     }
 }
 declare module BABYLON.GLTF2.Exporter {
@@ -719,6 +720,16 @@ declare module BABYLON.GLTF2.Exporter {
          */
         writeAttributeData(vertexBufferKind: string, attributeComponentKind: AccessorComponentType, meshAttributeArray: FloatArray, stride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean, babylonTransformNode: TransformNode): void;
         /**
+         * Writes mesh attribute data to a data buffer
+         * Returns the bytelength of the data
+         * @param vertexBufferKind Indicates what kind of vertex data is being passed in
+         * @param meshAttributeArray Array containing the attribute data
+         * @param byteStride Specifies the space between data
+         * @param binaryWriter The buffer to write the binary data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
+         */
+        writeMorphTargetAttributeData(vertexBufferKind: string, attributeComponentKind: AccessorComponentType, meshPrimitive: SubMesh, morphTarget: MorphTarget, meshAttributeArray: FloatArray, morphTargetAttributeArray: FloatArray, stride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean, minMax?: any): void;
+        /**
          * Generates glTF json data
          * @param shouldUseGlb Indicates whether the json should be written for a glb file
          * @param glTFPrefix Text to use when prefixing a glTF file
@@ -766,6 +777,14 @@ declare module BABYLON.GLTF2.Exporter {
          */
         private createBufferViewKind;
         /**
+     * Creates a bufferview based on the vertices type for the Babylon mesh
+     * @param babylonSubMesh The Babylon submesh that the morph target is applied to
+     * @param babylonMorphTarget the morph target to be exported
+     * @param binaryWriter The buffer to write the bufferview data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
+     */
+        private setMorphTargetAttributes;
+        /**
          * The primitive mode of the Babylon mesh
          * @param babylonMesh The BabylonJS mesh
          */
@@ -941,7 +960,7 @@ declare module BABYLON.GLTF2.Exporter {
         /**
          * The glTF accessor type for the data.
          */
-        dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4;
+        dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4 | AccessorType.SCALAR;
         /**
          * Specifies if quaternions should be used.
          */
@@ -983,8 +1002,25 @@ declare module BABYLON.GLTF2.Exporter {
             [key: number]: number;
         }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
         /**
+     * @ignore
+     * Create individual morph animations from the mesh's morph target animation tracks
+     * @param babylonNode
+     * @param runtimeGLTFAnimation
+     * @param idleGLTFAnimations
+     * @param nodeMap
+     * @param nodes
+     * @param binaryWriter
+     * @param bufferViews
+     * @param accessors
+     * @param convertToRightHandedSystem
+     * @param animationSampleRate
+     */
+        static _CreateMorphTargetAnimationFromMorphTargets(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
+            [key: number]: number;
+        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
+        /**
          * @ignore
-         * Create node animations from the animation groups
+         * Create node and morph animations from the animation groups
          * @param babylonScene
          * @param glTFAnimations
          * @param nodeMap

+ 402 - 30
dist/preview release/serializers/babylonjs.serializers.js

@@ -614,7 +614,7 @@ var KHR_lights_punctual = /** @class */ (function () {
     }
     /** @hidden */
     KHR_lights_punctual.prototype.dispose = function () {
-        delete this._lights;
+        this._lights = null;
     };
     Object.defineProperty(KHR_lights_punctual.prototype, "wasUsed", {
         /** @hidden */
@@ -1137,6 +1137,8 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
+
 /**
  * @hidden
  * Enum for handling in tangent and out tangent.
@@ -1230,6 +1232,11 @@ var _GLTFAnimation = /** @class */ (function () {
                 animationChannelTargetPath = "rotation" /* ROTATION */;
                 break;
             }
+            case 'influence': {
+                dataAccessorType = "SCALAR" /* SCALAR */;
+                animationChannelTargetPath = "weights" /* WEIGHTS */;
+                break;
+            }
             default: {
                 babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Tools"].Error("Unsupported animatable property " + property[0]);
             }
@@ -1279,8 +1286,63 @@ var _GLTFAnimation = /** @class */ (function () {
         }
     };
     /**
+ * @ignore
+ * Create individual morph animations from the mesh's morph target animation tracks
+ * @param babylonNode
+ * @param runtimeGLTFAnimation
+ * @param idleGLTFAnimations
+ * @param nodeMap
+ * @param nodes
+ * @param binaryWriter
+ * @param bufferViews
+ * @param accessors
+ * @param convertToRightHandedSystem
+ * @param animationSampleRate
+ */
+    _GLTFAnimation._CreateMorphTargetAnimationFromMorphTargets = function (babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
+        var glTFAnimation;
+        if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Mesh"]) {
+            var morphTargetManager = babylonNode.morphTargetManager;
+            if (morphTargetManager) {
+                for (var i = 0; i < morphTargetManager.numTargets; ++i) {
+                    var morphTarget = morphTargetManager.getTarget(i);
+                    for (var j = 0; j < morphTarget.animations.length; ++j) {
+                        var animation = morphTarget.animations[j];
+                        var combinedAnimation = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"]("" + animation.name, "influence", animation.framePerSecond, animation.dataType, animation.loopMode, animation.enableBlending);
+                        var combinedAnimationKeys = [];
+                        var animationKeys = animation.getKeys();
+                        for (var k = 0; k < animationKeys.length; ++k) {
+                            var animationKey = animationKeys[k];
+                            for (var l = 0; l < morphTargetManager.numTargets; ++l) {
+                                if (l == i) {
+                                    combinedAnimationKeys.push(animationKey);
+                                }
+                                else {
+                                    combinedAnimationKeys.push({ frame: animationKey.frame, value: morphTargetManager.getTarget(l).influence });
+                                }
+                            }
+                        }
+                        combinedAnimation.setKeys(combinedAnimationKeys);
+                        var animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimation);
+                        if (animationInfo) {
+                            glTFAnimation = {
+                                name: combinedAnimation.name,
+                                samplers: [],
+                                channels: []
+                            };
+                            _GLTFAnimation.AddAnimation("" + animation.name, animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation, babylonNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate, morphTargetManager.numTargets);
+                            if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {
+                                idleGLTFAnimations.push(glTFAnimation);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    };
+    /**
      * @ignore
-     * Create node animations from the animation groups
+     * Create node and morph animations from the animation groups
      * @param babylonScene
      * @param glTFAnimations
      * @param nodeMap
@@ -1292,18 +1354,22 @@ var _GLTFAnimation = /** @class */ (function () {
      * @param animationSampleRate
      */
     _GLTFAnimation._CreateNodeAnimationFromAnimationGroups = function (babylonScene, glTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystemMap, animationSampleRate) {
+        var _a;
         var glTFAnimation;
         if (babylonScene.animationGroups) {
             var animationGroups = babylonScene.animationGroups;
-            for (var _i = 0, animationGroups_1 = animationGroups; _i < animationGroups_1.length; _i++) {
-                var animationGroup = animationGroups_1[_i];
+            var _loop_1 = function (animationGroup) {
+                var morphAnimations = new Map();
+                var sampleAnimations = new Map();
+                var morphAnimationMeshes = new Set();
+                var animationGroupFrameDiff = animationGroup.to - animationGroup.from;
                 glTFAnimation = {
                     name: animationGroup.name,
                     channels: [],
                     samplers: []
                 };
-                for (var _a = 0, _b = animationGroup.targetedAnimations; _a < _b.length; _a++) {
-                    var targetAnimation = _b[_a];
+                var _loop_2 = function (i) {
+                    var targetAnimation = animationGroup.targetedAnimations[i];
                     var target = targetAnimation.target;
                     var animation = targetAnimation.animation;
                     if (target instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TransformNode"] || target.length === 1 && target[0] instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]) {
@@ -1314,15 +1380,87 @@ var _GLTFAnimation = /** @class */ (function () {
                             _GLTFAnimation.AddAnimation("" + animation.name, glTFAnimation, babylonTransformNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate);
                         }
                     }
+                    else if (target instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["MorphTarget"] || target.length === 1 && target[0] instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["MorphTarget"]) {
+                        var animationInfo = _GLTFAnimation._DeduceAnimationInfo(targetAnimation.animation);
+                        if (animationInfo) {
+                            var babylonMorphTarget_1 = target instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["MorphTarget"] ? target : target[0];
+                            if (babylonMorphTarget_1) {
+                                var babylonMorphTargetManager_1 = babylonScene.morphTargetManagers.find(function (morphTargetManager) {
+                                    for (var j = 0; j < morphTargetManager.numTargets; ++j) {
+                                        if (morphTargetManager.getTarget(j) === babylonMorphTarget_1) {
+                                            return true;
+                                        }
+                                    }
+                                    return false;
+                                });
+                                if (babylonMorphTargetManager_1) {
+                                    var babylonMesh = babylonScene.meshes.find(function (mesh) {
+                                        return mesh.morphTargetManager === babylonMorphTargetManager_1;
+                                    });
+                                    if (babylonMesh) {
+                                        if (!morphAnimations.has(babylonMesh)) {
+                                            morphAnimations.set(babylonMesh, new Map());
+                                        }
+                                        (_a = morphAnimations.get(babylonMesh)) === null || _a === void 0 ? void 0 : _a.set(babylonMorphTarget_1, animation);
+                                        morphAnimationMeshes.add(babylonMesh);
+                                        sampleAnimations.set(babylonMesh, animation);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                };
+                for (var i = 0; i < animationGroup.targetedAnimations.length; ++i) {
+                    _loop_2(i);
                 }
+                morphAnimationMeshes.forEach(function (mesh) {
+                    // for each mesh that we want to export a Morph target animation track for...
+                    var morphTargetManager = mesh.morphTargetManager;
+                    var combinedAnimationGroup = null;
+                    var animationKeys = [];
+                    var sampleAnimation = sampleAnimations.get(mesh);
+                    var numAnimationKeys = sampleAnimation.getKeys().length;
+                    // for each frame of this mesh's animation group track
+                    for (var i = 0; i < numAnimationKeys; ++i) {
+                        // construct a new Animation track by interlacing the frames of each morph target animation track
+                        if (morphTargetManager) {
+                            for (var j = 0; j < morphTargetManager.numTargets; ++j) {
+                                var morphTarget = morphTargetManager.getTarget(j);
+                                var animationsByMorphTarget = morphAnimations.get(mesh);
+                                if (animationsByMorphTarget) {
+                                    var morphTargetAnimation = animationsByMorphTarget.get(morphTarget);
+                                    if (morphTargetAnimation) {
+                                        if (!combinedAnimationGroup) {
+                                            combinedAnimationGroup = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"](animationGroup.name + "_" + mesh.name + "_MorphWeightAnimation", "influence", morphTargetAnimation.framePerSecond, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONTYPE_FLOAT, morphTargetAnimation.loopMode, morphTargetAnimation.enableBlending);
+                                        }
+                                        animationKeys.push(morphTargetAnimation.getKeys()[i]);
+                                    }
+                                    else {
+                                        animationKeys.push({ frame: animationGroup.from + (animationGroupFrameDiff / numAnimationKeys) * i, value: morphTarget.influence });
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    combinedAnimationGroup.setKeys(animationKeys);
+                    var animationInfo = _GLTFAnimation._DeduceAnimationInfo(combinedAnimationGroup);
+                    if (animationInfo) {
+                        _GLTFAnimation.AddAnimation(animationGroup.name + "_" + mesh.name + "_MorphWeightAnimation", glTFAnimation, mesh, combinedAnimationGroup, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, false, animationInfo.useQuaternion, animationSampleRate, morphTargetManager === null || morphTargetManager === void 0 ? void 0 : morphTargetManager.numTargets);
+                    }
+                });
                 if (glTFAnimation.channels.length && glTFAnimation.samplers.length) {
                     glTFAnimations.push(glTFAnimation);
                 }
+            };
+            for (var _i = 0, animationGroups_1 = animationGroups; _i < animationGroups_1.length; _i++) {
+                var animationGroup = animationGroups_1[_i];
+                _loop_1(animationGroup);
             }
         }
     };
-    _GLTFAnimation.AddAnimation = function (name, glTFAnimation, babylonTransformNode, animation, dataAccessorType, animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, useQuaternion, animationSampleRate) {
-        var animationData = _GLTFAnimation._CreateNodeAnimation(babylonTransformNode, animation, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion, animationSampleRate);
+    _GLTFAnimation.AddAnimation = function (name, glTFAnimation, babylonTransformNode, animation, dataAccessorType, animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, useQuaternion, animationSampleRate, morphAnimationChannels) {
+        var animationData;
+        animationData = _GLTFAnimation._CreateNodeAnimation(babylonTransformNode, animation, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion, animationSampleRate);
         var bufferView;
         var accessor;
         var keyframeAccessorIndex;
@@ -1331,6 +1469,19 @@ var _GLTFAnimation = /** @class */ (function () {
         var animationSampler;
         var animationChannel;
         if (animationData) {
+            if (morphAnimationChannels) {
+                var index = 0;
+                var currentInput = 0;
+                var newInputs = [];
+                while (animationData.inputs.length > 0) {
+                    currentInput = animationData.inputs.shift();
+                    if (index % morphAnimationChannels == 0) {
+                        newInputs.push(currentInput);
+                    }
+                    index++;
+                }
+                animationData.inputs = newInputs;
+            }
             var nodeIndex = nodeMap[babylonTransformNode.uniqueId];
             // Creates buffer view and accessor for key frames.
             var byteLength = animationData.inputs.length * 4;
@@ -1344,7 +1495,7 @@ var _GLTFAnimation = /** @class */ (function () {
             keyframeAccessorIndex = accessors.length - 1;
             // create bufferview and accessor for keyed values.
             outputLength = animationData.outputs.length;
-            byteLength = dataAccessorType === "VEC3" /* VEC3 */ ? animationData.outputs.length * 12 : animationData.outputs.length * 16;
+            byteLength = _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetDataAccessorElementCount(dataAccessorType) * 4 * animationData.outputs.length;
             // check for in and out tangents
             bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, undefined, name + "  data view");
             bufferViews.push(bufferView);
@@ -1485,7 +1636,7 @@ var _GLTFAnimation = /** @class */ (function () {
         var animationType = animation.dataType;
         var cacheValue;
         inputs.push(time);
-        if (typeof value === "number") {
+        if (typeof value === "number" && babylonTransformNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]) {
             value = this._ConvertFactorToVector3OrQuaternion(value, babylonTransformNode, animation, animationType, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion);
         }
         if (value) {
@@ -1505,7 +1656,10 @@ var _GLTFAnimation = /** @class */ (function () {
                 }
                 outputs.push(quaternionCache.asArray());
             }
-            else {
+            else if (animationChannelTargetPath === "weights" /* WEIGHTS */) {
+                outputs.push([value]);
+            }
+            else { // scaling and position animation
                 cacheValue = value;
                 if (convertToRightHandedSystem && (animationChannelTargetPath !== "scale" /* SCALE */)) {
                     _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(cacheValue);
@@ -1626,29 +1780,34 @@ var _GLTFAnimation = /** @class */ (function () {
             }
             outputs.push(value); // scale  vector.
         }
-        else if (animationType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONTYPE_FLOAT) { // handles single component x, y, z or w component animation by using a base property and animating over a component.
-            newPositionRotationOrScale = this._ConvertFactorToVector3OrQuaternion(keyFrame.value, babylonTransformNode, animation, animationType, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion);
-            if (newPositionRotationOrScale) {
-                if (animationChannelTargetPath === "rotation" /* ROTATION */) {
-                    var posRotScale = useQuaternion ? newPositionRotationOrScale : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize();
-                    if (convertToRightHandedSystem) {
-                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(posRotScale);
-                        if (!babylonTransformNode.parent) {
-                            posRotScale = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArray([0, 1, 0, 0]).multiply(posRotScale);
+        else if (animationType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONTYPE_FLOAT) {
+            if (animationChannelTargetPath === "weights" /* WEIGHTS */) {
+                outputs.push([keyFrame.value]);
+            }
+            else { // handles single component x, y, z or w component animation by using a base property and animating over a component.
+                newPositionRotationOrScale = this._ConvertFactorToVector3OrQuaternion(keyFrame.value, babylonTransformNode, animation, animationType, animationChannelTargetPath, convertToRightHandedSystem, useQuaternion);
+                if (newPositionRotationOrScale) {
+                    if (animationChannelTargetPath === "rotation" /* ROTATION */) {
+                        var posRotScale = useQuaternion ? newPositionRotationOrScale : babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(newPositionRotationOrScale.y, newPositionRotationOrScale.x, newPositionRotationOrScale.z).normalize();
+                        if (convertToRightHandedSystem) {
+                            _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(posRotScale);
+                            if (!babylonTransformNode.parent) {
+                                posRotScale = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromArray([0, 1, 0, 0]).multiply(posRotScale);
+                            }
                         }
+                        outputs.push(posRotScale.asArray());
                     }
-                    outputs.push(posRotScale.asArray());
-                }
-                else if (animationChannelTargetPath === "translation" /* TRANSLATION */) {
-                    if (convertToRightHandedSystem) {
-                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(newPositionRotationOrScale);
-                        if (!babylonTransformNode.parent) {
-                            newPositionRotationOrScale.x *= -1;
-                            newPositionRotationOrScale.z *= -1;
+                    else if (animationChannelTargetPath === "translation" /* TRANSLATION */) {
+                        if (convertToRightHandedSystem) {
+                            _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(newPositionRotationOrScale);
+                            if (!babylonTransformNode.parent) {
+                                newPositionRotationOrScale.x *= -1;
+                                newPositionRotationOrScale.z *= -1;
+                            }
                         }
                     }
+                    outputs.push(newPositionRotationOrScale.asArray());
                 }
-                outputs.push(newPositionRotationOrScale.asArray());
             }
         }
         else if (animationType === babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Animation"].ANIMATIONTYPE_QUATERNION) {
@@ -1752,6 +1911,14 @@ var _GLTFAnimation = /** @class */ (function () {
                     tangent = [0, 0, 0, 0];
                 }
             }
+            else if (animationChannelTargetPath === "weights" /* WEIGHTS */) {
+                if (tangentValue) {
+                    tangent = [tangentValue];
+                }
+                else {
+                    tangent = [0];
+                }
+            }
             else {
                 if (tangentValue) {
                     tangent = tangentValue.asArray();
@@ -2498,6 +2665,103 @@ var _Exporter = /** @class */ (function () {
         }
     };
     /**
+     * Writes mesh attribute data to a data buffer
+     * Returns the bytelength of the data
+     * @param vertexBufferKind Indicates what kind of vertex data is being passed in
+     * @param meshAttributeArray Array containing the attribute data
+     * @param byteStride Specifies the space between data
+     * @param binaryWriter The buffer to write the binary data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
+     */
+    _Exporter.prototype.writeMorphTargetAttributeData = function (vertexBufferKind, attributeComponentKind, meshPrimitive, morphTarget, meshAttributeArray, morphTargetAttributeArray, stride, binaryWriter, convertToRightHandedSystem, minMax) {
+        var vertexAttributes = [];
+        var index;
+        var difference = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"]();
+        var difference4 = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"](0, 0, 0, 0);
+        switch (vertexBufferKind) {
+            case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind: {
+                for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
+                    index = meshPrimitive.indexStart + k * stride;
+                    var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(meshAttributeArray, index);
+                    var morphData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(morphTargetAttributeArray, index);
+                    difference = morphData.subtractToRef(vertexData, difference);
+                    if (convertToRightHandedSystem) {
+                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(difference);
+                    }
+                    if (minMax) {
+                        minMax.min.copyFromFloats(Math.min(difference.x, minMax.min.x), Math.min(difference.y, minMax.min.y), Math.min(difference.z, minMax.min.z));
+                        minMax.max.copyFromFloats(Math.max(difference.x, minMax.max.x), Math.max(difference.y, minMax.max.y), Math.max(difference.z, minMax.max.z));
+                    }
+                    vertexAttributes.push(difference.asArray());
+                }
+                break;
+            }
+            case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind: {
+                for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
+                    index = meshPrimitive.indexStart + k * stride;
+                    var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(meshAttributeArray, index);
+                    vertexData.normalize();
+                    var morphData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArray(morphTargetAttributeArray, index);
+                    morphData.normalize();
+                    difference = morphData.subtractToRef(vertexData, difference);
+                    if (convertToRightHandedSystem) {
+                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedNormalVector3FromRef(difference);
+                    }
+                    vertexAttributes.push(difference.asArray());
+                }
+                break;
+            }
+            case babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind: {
+                for (var k = meshPrimitive.verticesStart; k < meshPrimitive.verticesCount; ++k) {
+                    index = meshPrimitive.indexStart + k * (stride + 1);
+                    var vertexData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"].FromArray(meshAttributeArray, index);
+                    _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._NormalizeTangentFromRef(vertexData);
+                    var morphData = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector4"].FromArray(morphTargetAttributeArray, index);
+                    _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._NormalizeTangentFromRef(morphData);
+                    difference4 = morphData.subtractToRef(vertexData, difference4);
+                    if (convertToRightHandedSystem) {
+                        _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._GetRightHandedVector4FromRef(difference4);
+                    }
+                    vertexAttributes.push([difference4.x, difference4.y, difference4.z]);
+                }
+                break;
+            }
+            default: {
+                babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Unsupported Vertex Buffer Type: " + vertexBufferKind);
+                vertexAttributes = [];
+            }
+        }
+        var writeBinaryFunc;
+        switch (attributeComponentKind) {
+            case 5121 /* UNSIGNED_BYTE */: {
+                writeBinaryFunc = binaryWriter.setUInt8.bind(binaryWriter);
+                break;
+            }
+            case 5123 /* UNSIGNED_SHORT */: {
+                writeBinaryFunc = binaryWriter.setUInt16.bind(binaryWriter);
+                break;
+            }
+            case 5125 /* UNSIGNED_INT */: {
+                writeBinaryFunc = binaryWriter.setUInt32.bind(binaryWriter);
+            }
+            case 5126 /* FLOAT */: {
+                writeBinaryFunc = binaryWriter.setFloat32.bind(binaryWriter);
+                break;
+            }
+            default: {
+                babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Unsupported Attribute Component kind: " + attributeComponentKind);
+                return;
+            }
+        }
+        for (var _i = 0, vertexAttributes_2 = vertexAttributes; _i < vertexAttributes_2.length; _i++) {
+            var vertexAttribute = vertexAttributes_2[_i];
+            for (var _a = 0, vertexAttribute_2 = vertexAttribute; _a < vertexAttribute_2.length; _a++) {
+                var component = vertexAttribute_2[_a];
+                writeBinaryFunc(component);
+            }
+        }
+    };
+    /**
      * Generates glTF json data
      * @param shouldUseGlb Indicates whether the json should be written for a glb file
      * @param glTFPrefix Text to use when prefixing a glTF file
@@ -2769,6 +3033,67 @@ var _Exporter = /** @class */ (function () {
         }
     };
     /**
+ * Creates a bufferview based on the vertices type for the Babylon mesh
+ * @param babylonSubMesh The Babylon submesh that the morph target is applied to
+ * @param babylonMorphTarget the morph target to be exported
+ * @param binaryWriter The buffer to write the bufferview data to
+ * @param convertToRightHandedSystem Converts the values to right-handed
+ */
+    _Exporter.prototype.setMorphTargetAttributes = function (babylonSubMesh, meshPrimitive, babylonMorphTarget, binaryWriter, convertToRightHandedSystem) {
+        if (babylonMorphTarget) {
+            if (!meshPrimitive.targets) {
+                meshPrimitive.targets = [];
+            }
+            var target = {};
+            if (babylonMorphTarget.hasNormals) {
+                var vertexNormals = babylonSubMesh.getMesh().getVerticesData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind);
+                var morphNormals = babylonMorphTarget.getNormals();
+                var count = babylonSubMesh.verticesCount;
+                var byteStride = 12; // 3 x 4 byte floats
+                var byteLength = count * byteStride;
+                var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
+                this._bufferViews.push(bufferView);
+                var bufferViewIndex = this._bufferViews.length - 1;
+                var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "NORMAL", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
+                this._accessors.push(accessor);
+                target.NORMAL = this._accessors.length - 1;
+                this.writeMorphTargetAttributeData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].NormalKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexNormals, morphNormals, byteStride / 4, binaryWriter, convertToRightHandedSystem);
+            }
+            if (babylonMorphTarget.hasPositions) {
+                var vertexPositions = babylonSubMesh.getMesh().getVerticesData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind);
+                var morphPositions = babylonMorphTarget.getPositions();
+                var count = babylonSubMesh.verticesCount;
+                var byteStride = 12; // 3 x 4 byte floats
+                var byteLength = count * byteStride;
+                var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_POSITION");
+                this._bufferViews.push(bufferView);
+                var bufferViewIndex = this._bufferViews.length - 1;
+                var minMax = { min: new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](Infinity, Infinity, Infinity), max: new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"](-Infinity, -Infinity, -Infinity) };
+                var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "POSITION", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
+                this._accessors.push(accessor);
+                target.POSITION = this._accessors.length - 1;
+                this.writeMorphTargetAttributeData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].PositionKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexPositions, morphPositions, byteStride / 4, binaryWriter, convertToRightHandedSystem, minMax);
+                accessor.min = minMax.min.asArray();
+                accessor.max = minMax.max.asArray();
+            }
+            if (babylonMorphTarget.hasTangents) {
+                var vertexTangents = babylonSubMesh.getMesh().getVerticesData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind);
+                var morphTangents = babylonMorphTarget.getTangents();
+                var count = babylonSubMesh.verticesCount;
+                var byteStride = 12; // 3 x 4 byte floats
+                var byteLength = count * byteStride;
+                var bufferView = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateBufferView(0, binaryWriter.getByteOffset(), byteLength, byteStride, babylonMorphTarget.name + "_NORMAL");
+                this._bufferViews.push(bufferView);
+                var bufferViewIndex = this._bufferViews.length - 1;
+                var accessor = _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__["_GLTFUtilities"]._CreateAccessor(bufferViewIndex, babylonMorphTarget.name + " - " + "TANGENT", "VEC3" /* VEC3 */, 5126 /* FLOAT */, count, 0, null, null);
+                this._accessors.push(accessor);
+                target.TANGENT = this._accessors.length - 1;
+                this.writeMorphTargetAttributeData(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["VertexBuffer"].TangentKind, 5126 /* FLOAT */, babylonSubMesh, babylonMorphTarget, vertexTangents, morphTangents, byteStride / 4, binaryWriter, convertToRightHandedSystem);
+            }
+            meshPrimitive.targets.push(target);
+        }
+    };
+    /**
      * The primitive mode of the Babylon mesh
      * @param babylonMesh The BabylonJS mesh
      */
@@ -2906,6 +3231,7 @@ var _Exporter = /** @class */ (function () {
             var indexBufferViewIndex = null;
             var primitiveMode = this.getMeshPrimitiveMode(bufferMesh);
             var vertexAttributeBufferViews = {};
+            var morphTargetManager = bufferMesh.morphTargetManager;
             // For each BabylonMesh, create bufferviews for each 'kind'
             for (var _i = 0, attributeData_1 = attributeData; _i < attributeData_1.length; _i++) {
                 var attribute = attributeData_1[_i];
@@ -3031,6 +3357,13 @@ var _Exporter = /** @class */ (function () {
                         }
                         meshPrimitive.material = materialIndex;
                     }
+                    if (morphTargetManager) {
+                        var target = void 0;
+                        for (var i = 0; i < morphTargetManager.numTargets; ++i) {
+                            target = morphTargetManager.getTarget(i);
+                            this.setMorphTargetAttributes(submesh, meshPrimitive, target, binaryWriter, convertToRightHandedSystem);
+                        }
+                    }
                     mesh.primitives.push(meshPrimitive);
                     var promise = this._extensionsPostExportMeshPrimitiveAsync("postExport", meshPrimitive, submesh, binaryWriter);
                     if (promise) {
@@ -3217,6 +3550,7 @@ var _Exporter = /** @class */ (function () {
                                 nodeMap[babylonNode.uniqueId] = nodeIndex;
                                 if (!babylonScene.animationGroups.length && babylonNode.animations.length) {
                                     _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
+                                    _glTFAnimation__WEBPACK_IMPORTED_MODULE_5__["_GLTFAnimation"]._CreateMorphTargetAnimationFromMorphTargets(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, convertToRightHandedSystem, _this._animationSampleRate);
                                 }
                             });
                         }
@@ -3268,6 +3602,15 @@ var _Exporter = /** @class */ (function () {
             if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TransformNode"]) {
                 // Set transformation
                 _this.setNodeTransformation(node, babylonNode, convertToRightHandedSystem);
+                if (babylonNode instanceof babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Mesh"]) {
+                    var morphTargetManager = babylonNode.morphTargetManager;
+                    if (morphTargetManager && morphTargetManager.numTargets > 0) {
+                        mesh.weights = [];
+                        for (var i = 0; i < morphTargetManager.numTargets; ++i) {
+                            mesh.weights.push(morphTargetManager.getTarget(i).influence);
+                        }
+                    }
+                }
                 return _this.setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter, convertToRightHandedSystem).then(function () {
                     if (mesh.primitives.length) {
                         _this._meshes.push(mesh);
@@ -3988,7 +4331,7 @@ var _GLTFMaterialExporter = /** @class */ (function () {
                             else {
                                 reject("gltfMaterialExporter: Failed to get blob from image canvas!");
                             }
-                        });
+                        }, mimeType);
                     }
                 }
                 else {
@@ -4584,6 +4927,17 @@ var _GLTFMaterialExporter = /** @class */ (function () {
                     samplerIndex_1 = foundSamplerIndex;
                 }
                 var size = babylonTexture.getSize();
+                // Preserve texture mime type if defined
+                if (babylonTexture.mimeType) {
+                    switch (babylonTexture.mimeType) {
+                        case "image/jpeg":
+                            mimeType = "image/jpeg" /* JPEG */;
+                            break;
+                        case "image/png":
+                            mimeType = "image/png" /* PNG */;
+                            break;
+                    }
+                }
                 return _this._createBase64FromCanvasAsync(pixels, size.width, size.height, mimeType).then(function (base64Data) {
                     var textureInfo = _this._getTextureInfoFromBase64(base64Data, babylonTexture.name.replace(/\.\/|\/|\.\\|\\/g, "_"), mimeType, babylonTexture.coordinatesIndex, samplerIndex_1);
                     if (textureInfo) {
@@ -4949,6 +5303,24 @@ var _GLTFUtilities = /** @class */ (function () {
         var m = matrix.m;
         babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__["Matrix"].FromValuesToRef(m[0], m[1], -m[2], m[3], m[4], m[5], -m[6], m[7], -m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15], matrix);
     };
+    _GLTFUtilities._GetDataAccessorElementCount = function (accessorType) {
+        switch (accessorType) {
+            case "MAT2" /* MAT2 */:
+                return 4;
+            case "MAT3" /* MAT3 */:
+                return 9;
+            case "MAT4" /* MAT4 */:
+                return 16;
+            case "SCALAR" /* SCALAR */:
+                return 1;
+            case "VEC2" /* VEC2 */:
+                return 2;
+            case "VEC3" /* VEC3 */:
+                return 3;
+            case "VEC4" /* VEC4 */:
+                return 4;
+        }
+    };
     return _GLTFUtilities;
 }());
 

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.js.map


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 77 - 4
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -527,6 +527,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFUtilities" {
         static _GetRightHandedQuaternionArrayFromRef(quaternion: number[]): void;
         static _NormalizeTangentFromRef(tangent: Vector4): void;
         static _GetRightHandedMatrixFromRef(matrix: Matrix): void;
+        static _GetDataAccessorElementCount(accessorType: AccessorType): 1 | 3 | 2 | 4 | 9 | 16;
     }
 }
 declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
@@ -536,6 +537,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
     import { Node } from "babylonjs/node";
     import { TransformNode } from "babylonjs/Meshes/transformNode";
     import { SubMesh } from "babylonjs/Meshes/subMesh";
+    import { MorphTarget } from "babylonjs/Morph/morphTarget";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
     import { Texture } from "babylonjs/Materials/Textures/texture";
     import { Material } from "babylonjs/Materials/material";
@@ -762,6 +764,16 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          */
         writeAttributeData(vertexBufferKind: string, attributeComponentKind: AccessorComponentType, meshAttributeArray: FloatArray, stride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean, babylonTransformNode: TransformNode): void;
         /**
+         * Writes mesh attribute data to a data buffer
+         * Returns the bytelength of the data
+         * @param vertexBufferKind Indicates what kind of vertex data is being passed in
+         * @param meshAttributeArray Array containing the attribute data
+         * @param byteStride Specifies the space between data
+         * @param binaryWriter The buffer to write the binary data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
+         */
+        writeMorphTargetAttributeData(vertexBufferKind: string, attributeComponentKind: AccessorComponentType, meshPrimitive: SubMesh, morphTarget: MorphTarget, meshAttributeArray: FloatArray, morphTargetAttributeArray: FloatArray, stride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean, minMax?: any): void;
+        /**
          * Generates glTF json data
          * @param shouldUseGlb Indicates whether the json should be written for a glb file
          * @param glTFPrefix Text to use when prefixing a glTF file
@@ -809,6 +821,14 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          */
         private createBufferViewKind;
         /**
+     * Creates a bufferview based on the vertices type for the Babylon mesh
+     * @param babylonSubMesh The Babylon submesh that the morph target is applied to
+     * @param babylonMorphTarget the morph target to be exported
+     * @param binaryWriter The buffer to write the bufferview data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
+     */
+        private setMorphTargetAttributes;
+        /**
          * The primitive mode of the Babylon mesh
          * @param babylonMesh The BabylonJS mesh
          */
@@ -991,7 +1011,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFAnimation" {
         /**
          * The glTF accessor type for the data.
          */
-        dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4;
+        dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4 | AccessorType.SCALAR;
         /**
          * Specifies if quaternions should be used.
          */
@@ -1033,8 +1053,25 @@ declare module "babylonjs-serializers/glTF/2.0/glTFAnimation" {
             [key: number]: number;
         }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
         /**
+     * @ignore
+     * Create individual morph animations from the mesh's morph target animation tracks
+     * @param babylonNode
+     * @param runtimeGLTFAnimation
+     * @param idleGLTFAnimations
+     * @param nodeMap
+     * @param nodes
+     * @param binaryWriter
+     * @param bufferViews
+     * @param accessors
+     * @param convertToRightHandedSystem
+     * @param animationSampleRate
+     */
+        static _CreateMorphTargetAnimationFromMorphTargets(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
+            [key: number]: number;
+        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
+        /**
          * @ignore
-         * Create node animations from the animation groups
+         * Create node and morph animations from the animation groups
          * @param babylonScene
          * @param glTFAnimations
          * @param nodeMap
@@ -1834,6 +1871,7 @@ declare module BABYLON.GLTF2.Exporter {
         static _GetRightHandedQuaternionArrayFromRef(quaternion: number[]): void;
         static _NormalizeTangentFromRef(tangent: Vector4): void;
         static _GetRightHandedMatrixFromRef(matrix: Matrix): void;
+        static _GetDataAccessorElementCount(accessorType: AccessorType): 1 | 3 | 2 | 4 | 9 | 16;
     }
 }
 declare module BABYLON.GLTF2.Exporter {
@@ -2054,6 +2092,16 @@ declare module BABYLON.GLTF2.Exporter {
          */
         writeAttributeData(vertexBufferKind: string, attributeComponentKind: AccessorComponentType, meshAttributeArray: FloatArray, stride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean, babylonTransformNode: TransformNode): void;
         /**
+         * Writes mesh attribute data to a data buffer
+         * Returns the bytelength of the data
+         * @param vertexBufferKind Indicates what kind of vertex data is being passed in
+         * @param meshAttributeArray Array containing the attribute data
+         * @param byteStride Specifies the space between data
+         * @param binaryWriter The buffer to write the binary data to
+         * @param convertToRightHandedSystem Converts the values to right-handed
+         */
+        writeMorphTargetAttributeData(vertexBufferKind: string, attributeComponentKind: AccessorComponentType, meshPrimitive: SubMesh, morphTarget: MorphTarget, meshAttributeArray: FloatArray, morphTargetAttributeArray: FloatArray, stride: number, binaryWriter: _BinaryWriter, convertToRightHandedSystem: boolean, minMax?: any): void;
+        /**
          * Generates glTF json data
          * @param shouldUseGlb Indicates whether the json should be written for a glb file
          * @param glTFPrefix Text to use when prefixing a glTF file
@@ -2101,6 +2149,14 @@ declare module BABYLON.GLTF2.Exporter {
          */
         private createBufferViewKind;
         /**
+     * Creates a bufferview based on the vertices type for the Babylon mesh
+     * @param babylonSubMesh The Babylon submesh that the morph target is applied to
+     * @param babylonMorphTarget the morph target to be exported
+     * @param binaryWriter The buffer to write the bufferview data to
+     * @param convertToRightHandedSystem Converts the values to right-handed
+     */
+        private setMorphTargetAttributes;
+        /**
          * The primitive mode of the Babylon mesh
          * @param babylonMesh The BabylonJS mesh
          */
@@ -2276,7 +2332,7 @@ declare module BABYLON.GLTF2.Exporter {
         /**
          * The glTF accessor type for the data.
          */
-        dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4;
+        dataAccessorType: AccessorType.VEC3 | AccessorType.VEC4 | AccessorType.SCALAR;
         /**
          * Specifies if quaternions should be used.
          */
@@ -2318,8 +2374,25 @@ declare module BABYLON.GLTF2.Exporter {
             [key: number]: number;
         }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
         /**
+     * @ignore
+     * Create individual morph animations from the mesh's morph target animation tracks
+     * @param babylonNode
+     * @param runtimeGLTFAnimation
+     * @param idleGLTFAnimations
+     * @param nodeMap
+     * @param nodes
+     * @param binaryWriter
+     * @param bufferViews
+     * @param accessors
+     * @param convertToRightHandedSystem
+     * @param animationSampleRate
+     */
+        static _CreateMorphTargetAnimationFromMorphTargets(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
+            [key: number]: number;
+        }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
+        /**
          * @ignore
-         * Create node animations from the animation groups
+         * Create node and morph animations from the animation groups
          * @param babylonScene
          * @param glTFAnimations
          * @param nodeMap

+ 103 - 62
dist/preview release/viewer/babylon.module.d.ts

@@ -9534,6 +9534,7 @@ declare module "babylonjs/Actions/action" {
     import { Observable } from "babylonjs/Misc/observable";
     import { Condition } from "babylonjs/Actions/condition";
     import { AbstractActionManager } from "babylonjs/Actions/abstractActionManager";
+    import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
     import { ActionManager } from "babylonjs/Actions/actionManager";
     import { ActionEvent } from "babylonjs/Actions/actionEvent";
@@ -9573,7 +9574,7 @@ declare module "babylonjs/Actions/action" {
          * Internal only - manager for action
          * @hidden
          */
-        _actionManager: AbstractActionManager;
+        _actionManager: Nullable<AbstractActionManager>;
         /**
          * Adds action to chain of actions, may be a DoNothingAction
          * @param action defines the next action to execute
@@ -11924,7 +11925,6 @@ declare module "babylonjs/Materials/Textures/Procedurals/proceduralTexture" {
      * @see https://doc.babylonjs.com/how_to/how_to_use_procedural_textures
      */
     export class ProceduralTexture extends Texture {
-        isCube: boolean;
         /**
          * Define if the texture is enabled or not (disabled texture will not render)
          */
@@ -16443,6 +16443,8 @@ declare module "babylonjs/Bones/skeleton" {
         _numBonesWithLinkedTransformNode: number;
         /** @hidden */
         _hasWaitingData: Nullable<boolean>;
+        /** @hidden */
+        _waitingOverrideMeshId: Nullable<string>;
         /**
          * Specifies if the skeleton should be serialized
          */
@@ -24118,6 +24120,8 @@ declare module "babylonjs/Materials/Textures/texture" {
         private _delayedOnLoad;
         private _delayedOnError;
         private _mimeType?;
+        /** Returns the texture mime type if it was defined by a loader (undefined else) */
+        get mimeType(): string | undefined;
         /**
          * Observable triggered once the texture has been loaded.
          */
@@ -24320,7 +24324,6 @@ declare module "babylonjs/Materials/Textures/renderTargetTexture" {
      * Actually, It is the base of lot of effects in the framework like post process, shadows, effect layers and rendering pipelines...
      */
     export class RenderTargetTexture extends Texture {
-        isCube: boolean;
         /**
          * The texture will only be rendered once which can be useful to improve performance if everything in your render is static for instance.
          */
@@ -24365,10 +24368,6 @@ declare module "babylonjs/Materials/Textures/renderTargetTexture" {
          */
         renderSprites: boolean;
         /**
-         * Override the default coordinates mode to projection for RTT as it is the most common case for rendered textures.
-         */
-        coordinatesMode: number;
-        /**
          * Define the camera used to render the texture.
          */
         activeCamera: Nullable<Camera>;
@@ -24459,7 +24458,7 @@ declare module "babylonjs/Materials/Textures/renderTargetTexture" {
         _generateMipMaps: boolean;
         protected _renderingManager: RenderingManager;
         /** @hidden */
-        _waitingRenderList: string[];
+        _waitingRenderList?: string[];
         protected _doNotChangeAspectRatio: boolean;
         protected _currentRefreshId: number;
         protected _refreshRate: number;
@@ -29300,6 +29299,14 @@ declare module "babylonjs/Meshes/mesh" {
          */
         get source(): Nullable<Mesh>;
         /**
+         * Gets the list of clones of this mesh
+         * The scene must have been constructed with useClonedMeshMap=true for this to work!
+         * Note that useClonedMeshMap=true is the default setting
+         */
+        get cloneMeshMap(): Nullable<{
+            [id: string]: Mesh | undefined;
+        }>;
+        /**
          * Gets or sets a boolean indicating that this mesh does not use index buffer
          */
         get isUnIndexed(): boolean;
@@ -30407,11 +30414,13 @@ declare module "babylonjs/Cameras/camera" {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
+        protected _upVector: Vector3;
         /**
          * The vector the camera should consider as up.
          * (default is Vector3(0, 1, 0) aka Vector3.Up())
          */
-        upVector: Vector3;
+        set upVector(vec: Vector3);
+        get upVector(): Vector3;
         /**
          * Define the current limit on the left side for an orthographic camera
          * In scene unit
@@ -33276,11 +33285,13 @@ declare module "babylonjs/Meshes/abstractMesh" {
          * Gets or sets a boolean indicating that pointer move events must be supported on this mesh (false by default)
          */
         enablePointerMoveEvents: boolean;
+        private _renderingGroupId;
         /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see https://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
-        renderingGroupId: number;
+        get renderingGroupId(): number;
+        set renderingGroupId(value: number);
         private _material;
         /** Gets or sets current material */
         get material(): Nullable<Material>;
@@ -35065,7 +35076,7 @@ declare module "babylonjs/Materials/Textures/baseTexture" {
          * This is part of the texture as textures usually maps to one uv set.
          */
         coordinatesIndex: number;
-        private _coordinatesMode;
+        protected _coordinatesMode: number;
         /**
         * How a texture is mapped.
         *
@@ -35084,6 +35095,7 @@ declare module "babylonjs/Materials/Textures/baseTexture" {
         */
         set coordinatesMode(value: number);
         get coordinatesMode(): number;
+        private _wrapU;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -35091,7 +35103,9 @@ declare module "babylonjs/Materials/Textures/baseTexture" {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapU: number;
+        get wrapU(): number;
+        set wrapU(value: number);
+        private _wrapV;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -35099,7 +35113,8 @@ declare module "babylonjs/Materials/Textures/baseTexture" {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapV: number;
+        get wrapV(): number;
+        set wrapV(value: number);
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -40731,8 +40746,6 @@ declare module "babylonjs/scene" {
          * The material properties need to be setup according to the type of texture in use.
          */
         environmentBRDFTexture: BaseTexture;
-        /** @hidden */
-        protected _environmentTexture: Nullable<BaseTexture>;
         /**
          * Texture used in all pbr material as the reflection texture.
          * As in the majority of the scene they are the same (exception for multi room and so on),
@@ -42510,6 +42523,13 @@ declare module "babylonjs/scene" {
          */
         getMaterialByTags(tagsQuery: string, forEach?: (material: Material) => void): Material[];
         /**
+         * Get a list of transform nodes by tags
+         * @param tagsQuery defines the tags query to use
+         * @param forEach defines a predicate used to filter results
+         * @returns an array of TransformNode
+         */
+        getTransformNodesByTags(tagsQuery: string, forEach?: (transform: TransformNode) => void): TransformNode[];
+        /**
          * Overrides the default sort function applied in the renderging group to prepare the meshes.
          * This allowed control for front to back rendering or reversly depending of the special needs.
          *
@@ -42795,10 +42815,15 @@ declare module "babylonjs/abstractScene" {
          * Textures to keep.
          */
         textures: BaseTexture[];
+        /** @hidden */
+        protected _environmentTexture: Nullable<BaseTexture>;
         /**
-         * Environment texture for the scene
+         * Texture used in all pbr material as the reflection texture.
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
          */
-        environmentTexture: Nullable<BaseTexture>;
+        get environmentTexture(): Nullable<BaseTexture>;
+        set environmentTexture(value: Nullable<BaseTexture>);
         /**
          * The list of postprocesses added to the scene
          */
@@ -44312,7 +44337,6 @@ declare module "babylonjs/Cameras/arcRotateCamera" {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
-        protected _upVector: Vector3;
         protected _upToYMatrix: Matrix;
         protected _YToUpMatrix: Matrix;
         /**
@@ -52255,7 +52279,12 @@ declare module "babylonjs/Gizmos/gizmo" {
         /**
          * Ratio for the scale of the gizmo (Default: 1)
          */
-        scaleRatio: number;
+        protected _scaleRatio: number;
+        /**
+         * Ratio for the scale of the gizmo (Default: 1)
+         */
+        set scaleRatio(value: number);
+        get scaleRatio(): number;
         /**
          * If a custom mesh has been set (Default: false)
          */
@@ -52277,10 +52306,12 @@ declare module "babylonjs/Gizmos/gizmo" {
          * @param mesh The mesh to replace the default mesh of the gizmo
          */
         setCustomMesh(mesh: Mesh): void;
+        protected _updateGizmoRotationToMatchAttachedMesh: boolean;
         /**
          * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)
          */
-        updateGizmoRotationToMatchAttachedMesh: boolean;
+        set updateGizmoRotationToMatchAttachedMesh(value: boolean);
+        get updateGizmoRotationToMatchAttachedMesh(): boolean;
         /**
          * If set the gizmo's position will be updated to match the attached mesh each frame (Default: true)
          */
@@ -52421,9 +52452,7 @@ declare module "babylonjs/Gizmos/positionGizmo" {
          */
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         /** Fires an event when any of it's sub gizmos are dragged */
         onDragStartObservable: Observable<unknown>;
         /** Fires an event when any of it's sub gizmos are released from dragging */
@@ -52550,7 +52579,7 @@ declare module "babylonjs/Debug/axesViewer" {
         /**
          * Gets the hosting scene
          */
-        scene: Scene;
+        scene: Nullable<Scene>;
         /**
          * Gets or sets a number used to scale line length
          */
@@ -55638,9 +55667,7 @@ declare module "babylonjs/Gizmos/scaleGizmo" {
         uniformScaleGizmo: AxisScaleGizmo;
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         private _uniformScalingMesh;
         private _octahedron;
         private _sensitivity;
@@ -63036,10 +63063,6 @@ declare module "babylonjs/Materials/Textures/hdrCubeTexture" {
          * The texture URL.
          */
         url: string;
-        /**
-         * The texture coordinates mode. As this texture is stored in a cube format, please modify carefully.
-         */
-        coordinatesMode: number;
         protected _isBlocking: boolean;
         /**
          * Sets wether or not the texture is blocking during loading.
@@ -64219,8 +64242,6 @@ declare module "babylonjs/Materials/Textures/equiRectangularCubeTexture" {
         private _height;
         /** The URL to the image. */
         url: string;
-        /** The texture coordinates mode. As this texture is stored in a cube format, please modify carefully. */
-        coordinatesMode: number;
         /**
          * Instantiates an EquiRectangularCubeTexture from the following parameters.
          * @param url The location of the image
@@ -89036,7 +89057,7 @@ declare module BABYLON {
          * Internal only - manager for action
          * @hidden
          */
-        _actionManager: AbstractActionManager;
+        _actionManager: Nullable<AbstractActionManager>;
         /**
          * Adds action to chain of actions, may be a DoNothingAction
          * @param action defines the next action to execute
@@ -91285,7 +91306,6 @@ declare module BABYLON {
      * @see https://doc.babylonjs.com/how_to/how_to_use_procedural_textures
      */
     export class ProceduralTexture extends Texture {
-        isCube: boolean;
         /**
          * Define if the texture is enabled or not (disabled texture will not render)
          */
@@ -95643,6 +95663,8 @@ declare module BABYLON {
         _numBonesWithLinkedTransformNode: number;
         /** @hidden */
         _hasWaitingData: Nullable<boolean>;
+        /** @hidden */
+        _waitingOverrideMeshId: Nullable<string>;
         /**
          * Specifies if the skeleton should be serialized
          */
@@ -102909,6 +102931,8 @@ declare module BABYLON {
         private _delayedOnLoad;
         private _delayedOnError;
         private _mimeType?;
+        /** Returns the texture mime type if it was defined by a loader (undefined else) */
+        get mimeType(): string | undefined;
         /**
          * Observable triggered once the texture has been loaded.
          */
@@ -103090,7 +103114,6 @@ declare module BABYLON {
      * Actually, It is the base of lot of effects in the framework like post process, shadows, effect layers and rendering pipelines...
      */
     export class RenderTargetTexture extends Texture {
-        isCube: boolean;
         /**
          * The texture will only be rendered once which can be useful to improve performance if everything in your render is static for instance.
          */
@@ -103135,10 +103158,6 @@ declare module BABYLON {
          */
         renderSprites: boolean;
         /**
-         * Override the default coordinates mode to projection for RTT as it is the most common case for rendered textures.
-         */
-        coordinatesMode: number;
-        /**
          * Define the camera used to render the texture.
          */
         activeCamera: Nullable<Camera>;
@@ -103229,7 +103248,7 @@ declare module BABYLON {
         _generateMipMaps: boolean;
         protected _renderingManager: RenderingManager;
         /** @hidden */
-        _waitingRenderList: string[];
+        _waitingRenderList?: string[];
         protected _doNotChangeAspectRatio: boolean;
         protected _currentRefreshId: number;
         protected _refreshRate: number;
@@ -107904,6 +107923,14 @@ declare module BABYLON {
          */
         get source(): Nullable<Mesh>;
         /**
+         * Gets the list of clones of this mesh
+         * The scene must have been constructed with useClonedMeshMap=true for this to work!
+         * Note that useClonedMeshMap=true is the default setting
+         */
+        get cloneMeshMap(): Nullable<{
+            [id: string]: Mesh | undefined;
+        }>;
+        /**
          * Gets or sets a boolean indicating that this mesh does not use index buffer
          */
         get isUnIndexed(): boolean;
@@ -108996,11 +109023,13 @@ declare module BABYLON {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
+        protected _upVector: Vector3;
         /**
          * The vector the camera should consider as up.
          * (default is Vector3(0, 1, 0) aka Vector3.Up())
          */
-        upVector: Vector3;
+        set upVector(vec: Vector3);
+        get upVector(): Vector3;
         /**
          * Define the current limit on the left side for an orthographic camera
          * In scene unit
@@ -111744,11 +111773,13 @@ declare module BABYLON {
          * Gets or sets a boolean indicating that pointer move events must be supported on this mesh (false by default)
          */
         enablePointerMoveEvents: boolean;
+        private _renderingGroupId;
         /**
          * Specifies the rendering group id for this mesh (0 by default)
          * @see https://doc.babylonjs.com/resources/transparency_and_how_meshes_are_rendered#rendering-groups
          */
-        renderingGroupId: number;
+        get renderingGroupId(): number;
+        set renderingGroupId(value: number);
         private _material;
         /** Gets or sets current material */
         get material(): Nullable<Material>;
@@ -113480,7 +113511,7 @@ declare module BABYLON {
          * This is part of the texture as textures usually maps to one uv set.
          */
         coordinatesIndex: number;
-        private _coordinatesMode;
+        protected _coordinatesMode: number;
         /**
         * How a texture is mapped.
         *
@@ -113499,6 +113530,7 @@ declare module BABYLON {
         */
         set coordinatesMode(value: number);
         get coordinatesMode(): number;
+        private _wrapU;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -113506,7 +113538,9 @@ declare module BABYLON {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapU: number;
+        get wrapU(): number;
+        set wrapU(value: number);
+        private _wrapV;
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -113514,7 +113548,8 @@ declare module BABYLON {
         * | 1     | WRAP_ADDRESSMODE   |             |
         * | 2     | MIRROR_ADDRESSMODE |             |
         */
-        wrapV: number;
+        get wrapV(): number;
+        set wrapV(value: number);
         /**
         * | Value | Type               | Description |
         * | ----- | ------------------ | ----------- |
@@ -118975,8 +119010,6 @@ declare module BABYLON {
          * The material properties need to be setup according to the type of texture in use.
          */
         environmentBRDFTexture: BaseTexture;
-        /** @hidden */
-        protected _environmentTexture: Nullable<BaseTexture>;
         /**
          * Texture used in all pbr material as the reflection texture.
          * As in the majority of the scene they are the same (exception for multi room and so on),
@@ -120754,6 +120787,13 @@ declare module BABYLON {
          */
         getMaterialByTags(tagsQuery: string, forEach?: (material: Material) => void): Material[];
         /**
+         * Get a list of transform nodes by tags
+         * @param tagsQuery defines the tags query to use
+         * @param forEach defines a predicate used to filter results
+         * @returns an array of TransformNode
+         */
+        getTransformNodesByTags(tagsQuery: string, forEach?: (transform: TransformNode) => void): TransformNode[];
+        /**
          * Overrides the default sort function applied in the renderging group to prepare the meshes.
          * This allowed control for front to back rendering or reversly depending of the special needs.
          *
@@ -121012,10 +121052,15 @@ declare module BABYLON {
          * Textures to keep.
          */
         textures: BaseTexture[];
+        /** @hidden */
+        protected _environmentTexture: Nullable<BaseTexture>;
         /**
-         * Environment texture for the scene
+         * Texture used in all pbr material as the reflection texture.
+         * As in the majority of the scene they are the same (exception for multi room and so on),
+         * this is easier to reference from here than from all the materials.
          */
-        environmentTexture: Nullable<BaseTexture>;
+        get environmentTexture(): Nullable<BaseTexture>;
+        set environmentTexture(value: Nullable<BaseTexture>);
         /**
          * The list of postprocesses added to the scene
          */
@@ -122434,7 +122479,6 @@ declare module BABYLON {
          */
         get position(): Vector3;
         set position(newPosition: Vector3);
-        protected _upVector: Vector3;
         protected _upToYMatrix: Matrix;
         protected _YToUpMatrix: Matrix;
         /**
@@ -129899,7 +129943,12 @@ declare module BABYLON {
         /**
          * Ratio for the scale of the gizmo (Default: 1)
          */
-        scaleRatio: number;
+        protected _scaleRatio: number;
+        /**
+         * Ratio for the scale of the gizmo (Default: 1)
+         */
+        set scaleRatio(value: number);
+        get scaleRatio(): number;
         /**
          * If a custom mesh has been set (Default: false)
          */
@@ -129921,10 +129970,12 @@ declare module BABYLON {
          * @param mesh The mesh to replace the default mesh of the gizmo
          */
         setCustomMesh(mesh: Mesh): void;
+        protected _updateGizmoRotationToMatchAttachedMesh: boolean;
         /**
          * If set the gizmo's rotation will be updated to match the attached mesh each frame (Default: true)
          */
-        updateGizmoRotationToMatchAttachedMesh: boolean;
+        set updateGizmoRotationToMatchAttachedMesh(value: boolean);
+        get updateGizmoRotationToMatchAttachedMesh(): boolean;
         /**
          * If set the gizmo's position will be updated to match the attached mesh each frame (Default: true)
          */
@@ -130044,9 +130095,7 @@ declare module BABYLON {
          */
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         /** Fires an event when any of it's sub gizmos are dragged */
         onDragStartObservable: Observable<unknown>;
         /** Fires an event when any of it's sub gizmos are released from dragging */
@@ -130157,7 +130206,7 @@ declare module BABYLON.Debug {
         /**
          * Gets the hosting scene
          */
-        scene: Scene;
+        scene: Nullable<Scene>;
         /**
          * Gets or sets a number used to scale line length
          */
@@ -133006,9 +133055,7 @@ declare module BABYLON {
         uniformScaleGizmo: AxisScaleGizmo;
         private _meshAttached;
         private _nodeAttached;
-        private _updateGizmoRotationToMatchAttachedMesh;
         private _snapDistance;
-        private _scaleRatio;
         private _uniformScalingMesh;
         private _octahedron;
         private _sensitivity;
@@ -139856,10 +139903,6 @@ declare module BABYLON {
          * The texture URL.
          */
         url: string;
-        /**
-         * The texture coordinates mode. As this texture is stored in a cube format, please modify carefully.
-         */
-        coordinatesMode: number;
         protected _isBlocking: boolean;
         /**
          * Sets wether or not the texture is blocking during loading.
@@ -140964,8 +141007,6 @@ declare module BABYLON {
         private _height;
         /** The URL to the image. */
         url: string;
-        /** The texture coordinates mode. As this texture is stored in a cube format, please modify carefully. */
-        coordinatesMode: number;
         /**
          * Instantiates an EquiRectangularCubeTexture from the following parameters.
          * @param url The location of the image

+ 1 - 1
dist/preview release/viewer/babylon.viewer.d.ts

@@ -1416,7 +1416,7 @@ declare module BabylonViewer {
             /**
                 * Babylon's scene optimizer
                 */
-            sceneOptimizer: BABYLON.SceneOptimizer;
+            sceneOptimizer?: BABYLON.SceneOptimizer;
             /**
                 * Models displayed in this viewer.
                 */

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 521 - 521
dist/preview release/viewer/babylon.viewer.js


Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 14 - 14
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -1550,7 +1550,7 @@ declare module 'babylonjs-viewer/managers/sceneManager' {
             /**
                 * Babylon's scene optimizer
                 */
-            sceneOptimizer: SceneOptimizer;
+            sceneOptimizer?: SceneOptimizer;
             /**
                 * Models displayed in this viewer.
                 */

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

@@ -43,6 +43,7 @@
 - Added `AssetContainerTask` support to `AssetsManager` class ([MackeyK24](https://github.com/MackeyK24))
 - Changed DeviceSourceManager getInput contract to no longer return nullable values ([Drigax](https://github.com/drigax))
 - Photo Dome and Video Dome now use the same abstract class and support the same parameters ([#8771](https://github.com/BabylonJS/Babylon.js/issues/8771)) ([RaananW](https://github.com/RaananW))
+- Added `getTransformNodesByTags` support to `Scene` class ([MackeyK24](https://github.com/MackeyK24))
 
 ### Engine
 
@@ -84,7 +85,7 @@
 - Popup Window available (To be used in Curve Editor) ([pixelspace](https://github.com/devpixelspace))
 - Add support to update inspector when switching to a new scene ([belfortk](https://github.com/belfortk))
 - Hex Component for Hex inputs on layer masks. ([msDestiny14](https://github.com/msDestiny14))
-- View & edit textures in pop out inspector using 5 tools. Supports region selection and individual channel editing. ([DarraghBurkeMS](https://github.com/DarraghBurkeMS))
+- View & edit textures in pop out inspector using tools such as brush and floodfill. Supports region selection, individual channel editing, and resizing. ([DarraghBurkeMS](https://github.com/DarraghBurkeMS))
 
 ### Cameras
 
@@ -291,6 +292,7 @@
 - Fix the bounding box of instances that does not match the instance position / rotation / scaling ([Popov72](https://github.com/Popov72))
 - Fix an issue with sound updateOptions not updating the underlying sound buffer/html element ([RaananW](https://github.com/RaananW))
 - Fixed bug in sphereBuilder where top and bottom segments added 6 indices per triangle instead of 3. ([aWeirdo](https://github.com/aWeirdo))
+- Fixed issue with Babylon scene export of loaded glTF meshes.([Drigax]/(https://github.com/drigax))
 
 ## Breaking changes
 - `FollowCamera.target` was renamed to `FollowCamera.meshTarget` to not be in conflict with `TargetCamera.target` ([Deltakosh](https://github.com/deltakosh))

+ 56 - 0
gui/src/2D/controls/textBlock.ts

@@ -39,6 +39,8 @@ export class TextBlock extends Control {
     private _lineSpacing: ValueAndUnit = new ValueAndUnit(0);
     private _outlineWidth: number = 0;
     private _outlineColor: string = "white";
+    private _underline: boolean = false;
+    private _lineThrough: boolean = false;
     /**
     * An event triggered after the text is changed
     */
@@ -196,6 +198,42 @@ export class TextBlock extends Control {
     }
 
     /**
+     * Gets or sets a boolean indicating that text must have underline
+     */
+    public get underline(): boolean {
+        return this._underline;
+    }
+
+    /**
+     * Gets or sets a boolean indicating that text must have underline
+     */
+    public set underline(value: boolean) {
+        if (this._underline === value) {
+            return;
+        }
+        this._underline = value;
+        this._markAsDirty();
+    }
+
+    /**
+     * Gets or sets an boolean indicating that text must be crossed out
+     */
+    public get lineThrough(): boolean {
+        return this._lineThrough;
+    }
+
+    /**
+     * Gets or sets an boolean indicating that text must be crossed out
+     */
+    public set lineThrough(value: boolean) {
+        if (this._lineThrough === value) {
+            return;
+        }
+        this._lineThrough = value;
+        this._markAsDirty();
+    }
+
+    /**
      * Gets or sets outlineColor of the text to display
      */
     public get outlineColor(): string {
@@ -308,6 +346,24 @@ export class TextBlock extends Control {
             context.strokeText(text, this._currentMeasure.left + x, y);
         }
         context.fillText(text, this._currentMeasure.left + x, y);
+
+        if (this._underline) {
+            context.beginPath();
+            context.lineWidth = Math.round(this.fontSizeInPixels * 0.05);
+            context.moveTo(this._currentMeasure.left + x, y + 3);
+            context.lineTo(this._currentMeasure.left + x + textWidth, y + 3);
+            context.stroke();
+            context.closePath();
+        }
+
+        if (this._lineThrough) {
+            context.beginPath();
+            context.lineWidth = Math.round(this.fontSizeInPixels * 0.05);
+            context.moveTo(this._currentMeasure.left + x, y - this.fontSizeInPixels / 3);
+            context.lineTo(this._currentMeasure.left + x + textWidth, y - this.fontSizeInPixels / 3);
+            context.stroke();
+            context.closePath();
+        }
     }
 
     /** @hidden */

+ 0 - 6
gui/src/3D/materials/fluentMaterial.ts

@@ -49,12 +49,6 @@ export class FluentMaterial extends PushMaterial {
     public innerGlowColor = new Color3(1.0, 1.0, 1.0);
 
     /**
-     * Gets or sets alpha value (default is 1.0)
-     */
-    @serialize()
-    public alpha = 1.0;
-
-    /**
      * Gets or sets the albedo color (Default is Color3(0.3, 0.35, 0.4))
      */
     @serializeAsColor3()

+ 118 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/canvasShader.ts

@@ -0,0 +1,118 @@
+export const canvasShader = {
+    path: {
+        vertexSource: `
+            precision highp float;
+
+            attribute vec3 position;
+            attribute vec2 uv;
+
+            uniform mat4 worldViewProjection;
+
+            varying vec2 vUV;
+
+            void main(void) {
+                gl_Position = worldViewProjection * vec4(position, 1.0);
+                vUV = uv;
+            }
+        `,
+        fragmentSource: `
+            precision highp float;
+    
+            uniform sampler2D textureSampler;
+    
+            uniform bool r;
+            uniform bool g;
+            uniform bool b;
+            uniform bool a;
+
+            uniform int x1;
+            uniform int y1;
+            uniform int x2;
+            uniform int y2;
+            uniform int w;
+            uniform int h;
+
+            uniform int time;
+            uniform bool showGrid;
+    
+            varying vec2 vUV;
+
+            float scl = 200.0;
+            float speed = 10.0 / 1000.0;
+            float smoothing = 0.2;
+    
+            void main(void) {
+                vec2 pos2 = vec2(gl_FragCoord.x, gl_FragCoord.y);
+                vec2 pos = floor(pos2 * 0.05);
+                float pattern = mod(pos.x + pos.y, 2.0); 
+                if (pattern == 0.0) {
+                    pattern = 0.7;
+                }
+                vec4 bg = vec4(pattern, pattern, pattern, 1.0);
+                vec4 col = texture(textureSampler, vUV);
+                if (!r && !g && !b) {
+                    if (a) {
+                        col = vec4(col.a, col.a, col.a, 1.0);
+                    } else {
+                        col = vec4(0.0,0.0,0.0,0.0);
+                    }
+                } else {
+                    if (!r) {
+                        col.r = 0.0;
+                        if (!b) {
+                            col.r = col.g;
+                        }
+                        else if (!g) {
+                            col.r = col.b;
+                        }
+                    }
+                    if (!g) {
+                        col.g = 0.0;
+                        if (!b) {
+                            col.g = col.r;
+                        }
+                        else if (!r) {
+                            col.g = col.b;
+                        }
+                    }
+                    if (!b) {
+                        col.b = 0.0;
+                        if (!r) {
+                            col.b = col.g;
+                        } else if (!g) {
+                            col.b = col.r;
+                        }
+                    }
+                    if (!a) {
+                        col.a = 1.0;
+                    }
+                }
+                gl_FragColor = col * (col.a) + bg * (1.0 - col.a);
+                float wF = float(w);
+                float hF = float(h);
+                int xPixel = int(floor(vUV.x * wF));
+                int yPixel = int(floor((1.0 - vUV.y) * hF));
+                int xDis = min(abs(xPixel - x1), abs(xPixel - x2));
+                int yDis = min(abs(yPixel - y1), abs(yPixel - y2));
+                if (showGrid) {
+                    vec2 frac = fract(vUV * vec2(wF,hF));
+                    float thickness = 0.1;
+                    if (abs(frac.x) < thickness || abs (frac.y) < thickness) {
+                        gl_FragColor = vec4(0.75,0.75,0.75,1.0);
+                    }
+                }
+                if (xPixel >= x1 && yPixel >= y1 && xPixel <= x2 && yPixel <= y2) {
+                    if (xDis <= 4 || yDis <= 4) {
+                        float c = sin(vUV.x * scl + vUV.y * scl + float(time) * speed);
+                        c = smoothstep(-smoothing,smoothing,c);
+                        float val = 1.0 - c;
+                        gl_FragColor = vec4(val, val, val, 1.0) * 0.7 + gl_FragColor * 0.3;
+                    }
+                }
+            }`
+    },
+    options: {
+        attributes: ['position', 'uv'],
+        uniforms: ['worldViewProjection', 'textureSampler', 'r', 'g', 'b', 'a', 'x1', 'y1', 'x2', 'y2', 'w', 'h', 'time', 'showGrid']
+    }
+}

+ 2 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/defaultTools/contrast.tsx

@@ -48,8 +48,8 @@ class contrastTool implements IToolType {
     cleanup() {
     }
     onReset() {
-        this.contrast = 0;
-        this.exposure = 0;
+        this.setExposure(0);
+        this.setContrast(0);
     }
 };
 

+ 1 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/defaultTools/floodfill.ts

@@ -26,7 +26,7 @@ export const Floodfill : IToolData = {
         setup () {
             this.pointerObserver = this.getParameters().scene.onPointerObservable.add((pointerInfo) => {
                 if (pointerInfo.pickInfo?.hit) {
-                    if (pointerInfo.type === PointerEventTypes.POINTERDOWN) {
+                    if (pointerInfo.type === PointerEventTypes.POINTERDOWN && pointerInfo.event.button === 0) {
                         this.fill();
                     }
                 }

+ 17 - 19
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/defaultTools/paintbrush.tsx

@@ -26,30 +26,28 @@ class paintbrushTool implements IToolType {
             x -= metadata.select.x1;
             y -= metadata.select.y1;
         }
+        const {ctx} = this;
+        let numSteps, stepVector;
+        stepVector = new Vector2();
         if (this.mousePos == null) {
             this.mousePos = new Vector2(x, y);
+            numSteps = 1;
+        } else {
+            const maxDistance = this.width / 4;
+            const diffVector = new Vector2(x - this.mousePos.x, y - this.mousePos.y);
+            numSteps = Math.ceil(diffVector.length() / maxDistance);
+            const trueDistance = diffVector.length() / numSteps;
+            stepVector = diffVector.normalize().multiplyByFloats(trueDistance, trueDistance);
         }
-        const {ctx} = this;
-        let xx = this.mousePos.x;
-        let yy = this.mousePos.y;
-        let stepCount = 0;
-        const distance = this.width / 4;
-        const step = new Vector2(x - this.mousePos.x, y - this.mousePos.y).normalize().multiplyByFloats(distance, distance);
-        const numSteps = new Vector2(x - this.mousePos.x, y - this.mousePos.y).length() / distance;
-        while(stepCount < numSteps) {
+        let paintVector = this.mousePos.clone();
+        for(let stepCount = 0; stepCount < numSteps; stepCount++) {
             ctx.globalAlpha = 1.0;
             ctx.globalCompositeOperation = 'destination-out';
-            ctx.drawImage(this.circleCanvas, Math.floor(xx - this.width / 2), Math.floor(yy - this.width / 2));
+            ctx.drawImage(this.circleCanvas, Math.ceil(paintVector.x - this.width / 2), Math.ceil(paintVector.y - this.width / 2));
             ctx.globalAlpha = metadata.alpha;
             ctx.globalCompositeOperation = 'source-over';
-            ctx.drawImage(this.circleCanvas, Math.floor(xx - this.width / 2), Math.floor(yy - this.width / 2));
-            xx += step.x;
-            yy += step.y;
-            stepCount++;
-            if (numSteps - stepCount < 1) {
-                xx = x;
-                yy = y;
-            }
+            ctx.drawImage(this.circleCanvas, Math.ceil(paintVector.x - this.width / 2), Math.ceil(paintVector.y - this.width / 2));
+            paintVector.addInPlace(stepVector);
         }
         updatePainting();
         this.mousePos = new Vector2(x,y);
@@ -80,8 +78,8 @@ class paintbrushTool implements IToolType {
                         const g = Math.floor(rgb.g * 255);
                         const b = Math.floor(rgb.b * 255);
                         let idx = 0;
-                        for(let y = -Math.ceil(this.width / 2); y < Math.floor(this.width / 2); y++) {
-                            for (let x = -Math.ceil(this.width / 2); x < Math.floor(this.width / 2); x++) {
+                        for(let y = -Math.floor(this.width / 2); y < Math.ceil(this.width / 2); y++) {
+                            for (let x = -Math.floor(this.width / 2); x < Math.ceil(this.width / 2); x++) {
                                 pixels[idx++] = r;
                                 pixels[idx++] = g;
                                 pixels[idx++] = b;

+ 16 - 4
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/propertiesBar.tsx

@@ -1,9 +1,11 @@
 import * as React from 'react';
 import { BaseTexture } from 'babylonjs/Materials/Textures/baseTexture';
 import { IPixelData } from './textureCanvasManager';
+import { ISize } from 'babylonjs/Maths/math.size';
 
 interface IPropertiesBarProps {
     texture: BaseTexture;
+    size: ISize;
     saveTexture(): void;
     pixelData: IPixelData;
     face: number;
@@ -21,7 +23,7 @@ interface IPropertiesBarState {
 }
 
 interface IPixelDataProps {
-    name : string;
+    name: string;
     data: number | undefined;
 }
 
@@ -50,8 +52,8 @@ export class PropertiesBar extends React.PureComponent<IPropertiesBarProps,IProp
         super(props);
 
         this.state = {
-            width: props.texture.getSize().width,
-            height: props.texture.getSize().height
+            width: props.size.width,
+            height: props.size.height
         }
     }
 
@@ -69,8 +71,18 @@ export class PropertiesBar extends React.PureComponent<IPropertiesBarProps,IProp
         return oldDim;
     }
 
+    componentWillUpdate(nextProps: IPropertiesBarProps) {
+        if (nextProps.size.width != this.props.size.width || nextProps.size.height != this.props.size.height) {
+            this.setState({
+                width: nextProps.size.width,
+                height: nextProps.size.height
+            })
+        }
+    }
+
     render() {
         const {mipLevel, setMipLevel, pixelData, resizeTexture, texture, face, setFace, saveTexture, resetTexture, uploadTexture} = this.props;
+        const maxLevels = 1 + Math.floor(Math.log2(Math.max(texture.getSize().width, texture.getSize().height)));
         return <div id='properties'>
                 <div className='tab' id='logo-tab'>
                     <img className='icon' src={this._babylonLogo}/>
@@ -114,7 +126,7 @@ export class PropertiesBar extends React.PureComponent<IPropertiesBarProps,IProp
                     {!texture.noMipmap &&
                         <div className='tab' id='mip-tab'>
                             <img title='Mip Preview Up' className='icon button' src={this._mipUp} onClick={() => mipLevel > 0 && setMipLevel(mipLevel - 1)} />
-                            <img title='Mip Preview Down' className='icon button' src={this._mipDown} onClick={() => mipLevel < 12 && setMipLevel(mipLevel + 1)} />
+                            <img title='Mip Preview Down' className='icon button' src={this._mipDown} onClick={() => mipLevel < maxLevels && setMipLevel(mipLevel + 1)} />
                         </div>
                     }
                 </div>

+ 4 - 4
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/textureCanvasComponent.tsx

@@ -2,10 +2,10 @@ import * as React from 'react';
 import { BaseTexture } from 'babylonjs/Materials/Textures/baseTexture';
 
 interface ITextureCanvasComponentProps {
-    canvasUI : React.RefObject<HTMLCanvasElement>;
-    canvas2D : React.RefObject<HTMLCanvasElement>;
-    canvas3D : React.RefObject<HTMLCanvasElement>;
-    texture : BaseTexture;
+    canvasUI: React.RefObject<HTMLCanvasElement>;
+    canvas2D: React.RefObject<HTMLCanvasElement>;
+    canvas3D: React.RefObject<HTMLCanvasElement>;
+    texture: BaseTexture;
 }
 
 export class TextureCanvasComponent extends React.PureComponent<ITextureCanvasComponentProps> {

+ 51 - 136
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/textureCanvasManager.ts

@@ -4,7 +4,6 @@ import { Vector3, Vector2 } from 'babylonjs/Maths/math.vector';
 import { Color4, Color3 } from 'babylonjs/Maths/math.color';
 import { FreeCamera } from 'babylonjs/Cameras/freeCamera';
 import { Nullable } from 'babylonjs/types'
-
 import { PlaneBuilder } from 'babylonjs/Meshes/Builders/planeBuilder';
 import { Mesh } from 'babylonjs/Meshes/mesh';
 import { Camera } from 'babylonjs/Cameras/camera';
@@ -30,6 +29,8 @@ import { ITool } from './toolBar';
 import { IChannel } from './channelsBar';
 import { IMetadata } from './textureEditorComponent';
 
+import { canvasShader } from './canvasShader';
+
 
 export interface IPixelData {
     x? : number;
@@ -86,8 +87,8 @@ export class TextureCanvasManager {
     /* Tracks which keys are currently pressed */
     private _keyMap : any = {};
 
-    private static ZOOM_MOUSE_SPEED : number = 0.0005;
-    private static ZOOM_KEYBOARD_SPEED : number = 0.2;
+    private static ZOOM_MOUSE_SPEED : number = 0.001;
+    private static ZOOM_KEYBOARD_SPEED : number = 0.4;
     private static ZOOM_IN_KEY : string = '+';
     private static ZOOM_OUT_KEY : string = '-';
 
@@ -95,9 +96,12 @@ export class TextureCanvasManager {
     private static PAN_MOUSE_BUTTON : number = 1; // MMB
 
     private static MIN_SCALE : number = 0.01;
+    private static GRID_SCALE : number = 0.047;
     private static MAX_SCALE : number = 10;
 
     private static SELECT_ALL_KEY = 'KeyA';
+    private static SAVE_KEY ='KeyS';
+    private static RESET_KEY = 'KeyR';
     private static DESELECT_KEY = 'Escape'
 
     private _tool : Nullable<ITool>;
@@ -144,7 +148,7 @@ export class TextureCanvasManager {
         this._originalTexture = texture;
         this._originalInternalTexture = this._originalTexture._texture;
         this._engine = new Engine(this._UICanvas, true);
-        this._scene = new Scene(this._engine);
+        this._scene = new Scene(this._engine, {virtual: true});
         this._scene.clearColor = new Color4(0.11, 0.11, 0.11, 1.0);
 
         this._camera = new FreeCamera('camera', new Vector3(0, 0, -1), this._scene);
@@ -154,7 +158,7 @@ export class TextureCanvasManager {
         this._channelsTexture = new HtmlElementTexture('ct', this._2DCanvas, {engine: this._engine, scene: null, samplingMode: Texture.NEAREST_SAMPLINGMODE, generateMipMaps: true});
 
         this._3DEngine = new Engine(this._3DCanvas);
-        this._3DScene = new Scene(this._3DEngine);
+        this._3DScene = new Scene(this._3DEngine, {virtual: true});
         this._3DScene.clearColor = new Color4(0,0,0,0);
         this._3DCanvasTexture = new HtmlElementTexture('canvas', this._2DCanvas, {engine: this._3DEngine, scene: this._3DScene});
         this._3DCanvasTexture.hasAlpha = true;
@@ -170,117 +174,13 @@ export class TextureCanvasManager {
         mat.emissiveColor = Color3.White();
         this._3DPlane.material = mat;
 
+
         this._planeMaterial = new ShaderMaterial(
-            'shader',
+            'canvasShader',
             this._scene,
-            {
-                vertexSource: `
-                    precision highp float;
-
-                    attribute vec3 position;
-                    attribute vec2 uv;
-
-                    uniform mat4 worldViewProjection;
-
-                    varying vec2 vUV;
-
-                    void main(void) {
-                        gl_Position = worldViewProjection * vec4(position, 1.0);
-                        vUV = uv;
-                    }
-                `,
-                fragmentSource: `
-                    precision highp float;
-            
-                    uniform sampler2D textureSampler;
-            
-                    uniform bool r;
-                    uniform bool g;
-                    uniform bool b;
-                    uniform bool a;
-
-                    uniform int x1;
-                    uniform int y1;
-                    uniform int x2;
-                    uniform int y2;
-                    uniform int w;
-                    uniform int h;
-
-                    uniform int time;
-            
-                    varying vec2 vUV;
-
-                    float scl = 200.0;
-                    float speed = 10.0 / 1000.0;
-                    float smoothing = 0.2;
-            
-                    void main(void) {
-                        vec2 pos2 = vec2(gl_FragCoord.x, gl_FragCoord.y);
-                        vec2 pos = floor(pos2 * 0.05);
-                        float pattern = mod(pos.x + pos.y, 2.0); 
-                        if (pattern == 0.0) {
-                            pattern = 0.7;
-                        }
-                        vec4 bg = vec4(pattern, pattern, pattern, 1.0);
-                        vec4 col = texture(textureSampler, vUV);
-                        if (!r && !g && !b) {
-                            if (a) {
-                                col = vec4(col.a, col.a, col.a, 1.0);
-                            } else {
-                                col = vec4(0.0,0.0,0.0,0.0);
-                            }
-                        } else {
-                            if (!r) {
-                                col.r = 0.0;
-                                if (!b) {
-                                    col.r = col.g;
-                                }
-                                else if (!g) {
-                                    col.r = col.b;
-                                }
-                            }
-                            if (!g) {
-                                col.g = 0.0;
-                                if (!b) {
-                                    col.g = col.r;
-                                }
-                                else if (!r) {
-                                    col.g = col.b;
-                                }
-                            }
-                            if (!b) {
-                                col.b = 0.0;
-                                if (!r) {
-                                    col.b = col.g;
-                                } else if (!g) {
-                                    col.b = col.r;
-                                }
-                            }
-                            if (!a) {
-                                col.a = 1.0;
-                            }
-                        }
-                        gl_FragColor = col * (col.a) + bg * (1.0 - col.a);
-                        float wF = float(w);
-                        float hF = float(h);
-                        int xPixel = int(floor(vUV.x * wF));
-                        int yPixel = int(floor((1.0 - vUV.y) * hF));
-                        int xDis = min(abs(xPixel - x1), abs(xPixel - x2));
-                        int yDis = min(abs(yPixel - y1), abs(yPixel - y2));
-                        if (xPixel >= x1 && yPixel >= y1 && xPixel <= x2 && yPixel <= y2) {
-                            if (xDis <= 4 || yDis <= 4) {
-                                float c = sin(vUV.x * scl + vUV.y * scl + float(time) * speed);
-                                c = smoothstep(-smoothing,smoothing,c);
-                                float val = 1.0 - c;
-                                gl_FragColor = vec4(val, val, val, 1.0) * 0.7 + gl_FragColor * 0.3;
-                            }
-                        }
-                    }`
-            },
-        {
-            attributes: ['position', 'uv'],
-            uniforms: ['worldViewProjection', 'textureSampler', 'r', 'g', 'b', 'a', 'x1', 'y1', 'x2', 'y2', 'w', 'h', 'time']
-        });
+            canvasShader.path,
+            canvasShader.options
+        );
         
         this.grabOriginalTexture();
 
@@ -296,6 +196,7 @@ export class TextureCanvasManager {
         this._planeMaterial.setInt('w', this._size.width);
         this._planeMaterial.setInt('h', this._size.height);
         this._planeMaterial.setInt('time', 0);
+        this._planeMaterial.setFloat('showGrid', 0.0);
         this._plane.material = this._planeMaterial;
         
         this._window.addEventListener('keydown', evt => {
@@ -311,6 +212,14 @@ export class TextureCanvasManager {
                 });
                 evt.preventDefault();
             }
+            if (evt.code === TextureCanvasManager.SAVE_KEY && evt.ctrlKey) {
+                this.saveTexture();
+                evt.preventDefault();
+            }
+            if (evt.code === TextureCanvasManager.RESET_KEY && evt.ctrlKey) {
+                this.reset();
+                evt.preventDefault();
+            }
             if (evt.code === TextureCanvasManager.DESELECT_KEY) {
                 this._setMetadata({
                     select: {
@@ -331,13 +240,19 @@ export class TextureCanvasManager {
             this._engine.resize();
             this._scene.render();
             this._planeMaterial.setInt('time', new Date().getTime());
+            
         });
 
-        this._scale = 1.5;
+        this._scale =  1.5 / Math.max(this._size.width, this._size.height);
         this._isPanning = false;
 
         this._scene.onBeforeRenderObservable.add(() => {
-            this._scale = Math.min(Math.max(this._scale, TextureCanvasManager.MIN_SCALE), TextureCanvasManager.MAX_SCALE);
+            this._scale = Math.min(Math.max(this._scale, TextureCanvasManager.MIN_SCALE / Math.log2(Math.min(this._size.width, this._size.height))), TextureCanvasManager.MAX_SCALE);
+            if (this._scale > TextureCanvasManager.GRID_SCALE) {
+                this._planeMaterial.setFloat('showGrid', 1.0);
+            } else {
+                this._planeMaterial.setFloat('showGrid', 0.0);
+            }
             const ratio = this._UICanvas?.width / this._UICanvas?.height;
             const {x,y} = this._cameraPos;
             this._camera.orthoBottom = y - 1 / this._scale;
@@ -438,6 +353,7 @@ export class TextureCanvasManager {
     private queueTextureUpdate() {
         if (this._canUpdate) {
             (this._target as HtmlElementTexture).update((this._originalTexture as Texture).invertY);
+            this._target._texture?.updateSize(this._size.width, this._size.height);
             if (this._editing3D) {
                 this._imageData = this._3DEngine.readPixels(0, 0, this._size.width, this._size.height);
             } else {
@@ -495,6 +411,7 @@ export class TextureCanvasManager {
         ctx2D.fillStyle = 'white';
         ctx2D.fillRect(x,y,w,h);
         ctx2D.imageSmoothingEnabled = false;
+        // If we're not editing all channels, we must process the pixel data
         if (!editingAllChannels) {
             const newData = ctx.getImageData(0, 0, w, h);
             const nd = newData.data;
@@ -511,6 +428,7 @@ export class TextureCanvasManager {
         } else {
             ctx2D.globalCompositeOperation = 'source-over';
             ctx2D.globalAlpha = 1.0;
+            // We want to use drawImage wherever possible since it is much faster than putImageData
             ctx2D.drawImage(ctx.canvas, x, y);
         }
         this.updateTexture();
@@ -554,9 +472,9 @@ export class TextureCanvasManager {
         ctx.putImageData(imgData, 0, 0);
     }
 
-    public grabOriginalTexture(adjustZoom = true) {
+    public grabOriginalTexture() {
         // Grab image data from original texture and paint it onto the context of a DynamicTexture
-        this.setSize(this._originalTexture.getSize(), adjustZoom);
+        this.setSize(this._originalTexture.getSize());
         TextureHelper.GetTextureDataAsync(
             this._originalTexture,
             this._size.width,
@@ -620,7 +538,7 @@ export class TextureCanvasManager {
     public set face(face: number) {
         if (this._face !== face) {
             this._face = face;
-            this.grabOriginalTexture(false);
+            this.grabOriginalTexture();
             this.updateDisplay();
         }
     }
@@ -628,7 +546,7 @@ export class TextureCanvasManager {
     public set mipLevel(mipLevel : number) {
         if (this._mipLevel === mipLevel) return;
         this._mipLevel = mipLevel;
-        this.grabOriginalTexture(false);
+        this.grabOriginalTexture();
     }
 
     /** Returns the 3D scene used for postprocesses */
@@ -646,9 +564,8 @@ export class TextureCanvasManager {
     }
 
     private makePlane() {
-        const textureRatio = this._size.width / this._size.height;
         if (this._plane) this._plane.dispose();
-        this._plane = PlaneBuilder.CreatePlane("plane", {width: textureRatio, height: 1}, this._scene);
+        this._plane = PlaneBuilder.CreatePlane("plane", {width: this._size.width, height: this._size.height}, this._scene);
         this._plane.enableEdgesRendering();
         this._plane.edgesWidth = 4.0;
         this._plane.edgesColor = new Color4(1,1,1,1);
@@ -675,7 +592,8 @@ export class TextureCanvasManager {
         this._didEdit = true;
     }
 
-    public setSize(size: ISize, adjustZoom = true) {
+    public setSize(size: ISize) {
+        const oldSize = this._size;
         this._size = size;
         this._2DCanvas.width = this._size.width;
         this._2DCanvas.height = this._size.height;
@@ -683,10 +601,10 @@ export class TextureCanvasManager {
         this._3DCanvas.height = this._size.height;
         this._planeMaterial.setInt('w', this._size.width);
         this._planeMaterial.setInt('h', this._size.height);
-        if (adjustZoom) {
+        if (oldSize.width != size.width || oldSize.height != size.height) {
             this._cameraPos.x = 0;
             this._cameraPos.y = 0;
-            this._scale = 1.5 / (this._size.width/this._size.height);
+            this._scale = 1.5 / Math.max(this._size.width, this._size.height);
         }
         this.makePlane();
     }
@@ -706,17 +624,7 @@ export class TextureCanvasManager {
                 let base64data = reader.result as string;     
 
                 if (extension === '.dds' || extension === '.env') {
-                    const texture = new CubeTexture(
-                        base64data,
-                        this._scene,
-                        [extension],
-                        this._originalTexture.noMipmap,                        
-                        null,
-                        () => {
-                            // TO-DO: implement cube loading
-                            texture.dispose();
-                        }
-                    );
+                    (this._originalTexture as CubeTexture).updateURL(base64data, extension, () => this.grabOriginalTexture());
                 } else {
                     const texture = new Texture(
                         base64data,
@@ -743,6 +651,13 @@ export class TextureCanvasManager {
         }, undefined, true);
     }
 
+    public saveTexture() {
+        const canvas = this._editing3D ? this._3DCanvas : this._2DCanvas;
+        Tools.ToBlob(canvas, (blob) => {
+            Tools.Download(blob!, this._originalTexture.name);
+        });
+    }
+
     public dispose() {
         if (this._didEdit) {
             this._originalInternalTexture?.dispose();

+ 13 - 14
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/textureEditor.scss

@@ -79,6 +79,7 @@
                 }
                 label {
                     margin-left: 15px;
+                    font-size: 15px;
                     color: #afafaf;
                     input {
                         width: 40px;
@@ -86,8 +87,10 @@
                         background-color: #000000;
                         color: #ffffff;
                         border: 0;
-                        padding-left: 4px;
                         font-size: 12px;
+                        text-align: 'left';
+                        font-family: 'acumin-pro-condensed';
+                        font-size: 15px;
                     }
         
                     &:last-of-type {
@@ -110,6 +113,9 @@
             &:first-of-type {
                 margin-left: 15px;
             }
+            &:last-of-type {
+                padding-right: 15px;
+            }
             width: 45px;
             color: #afafaf;
             display: flex;
@@ -119,6 +125,7 @@
                 width: 30px;
                 color: white;
             }
+            font-size: 15px;
         }
     }
     
@@ -161,11 +168,6 @@
             }
         }
 
-        #color-picker {
-            position: absolute;
-            margin-left: 40px;
-        }
-
         #color {
             margin-top: 8px;
             #active-color-bg {
@@ -187,14 +189,7 @@
                 border-radius: 50%;
             }
         }
-        .color-picker-cover {
-            position: fixed;
-            top: 0;
-            left: 0;
-            right: 0;
-            bottom: 0;
-        }
-        .color-picker {
+        #color-picker {
             position: absolute;
             margin-left: 40px;
         }
@@ -222,6 +217,10 @@
             &:hover {
                 cursor: pointer;
             }
+
+            &:last-of-type {
+                border-bottom: none;
+            }
         }
         user-select: none;
     }

+ 24 - 6
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/textureEditorComponent.tsx

@@ -34,6 +34,7 @@ interface ITextureEditorComponentState {
     pixelData : IPixelData;
     face: number;
     mipLevel: number;
+    pickerOpen: boolean;
 }
 
 export interface IToolParameters {
@@ -117,6 +118,7 @@ export class TextureEditorComponent extends React.Component<ITextureEditorCompon
     private _UICanvas = React.createRef<HTMLCanvasElement>();
     private _2DCanvas = React.createRef<HTMLCanvasElement>();
     private _3DCanvas = React.createRef<HTMLCanvasElement>();
+    private _pickerRef = React.createRef<HTMLDivElement>();
     private _timer : number | null;
     private static PREVIEW_UPDATE_DELAY_MS = 160;
 
@@ -148,7 +150,8 @@ export class TextureEditorComponent extends React.Component<ITextureEditorCompon
             channels,
             pixelData: {},
             face: 0,
-            mipLevel: 0
+            mipLevel: 0,
+            pickerOpen: false
         }
         this.loadToolFromURL = this.loadToolFromURL.bind(this);
         this.changeTool = this.changeTool.bind(this);
@@ -157,7 +160,8 @@ export class TextureEditorComponent extends React.Component<ITextureEditorCompon
         this.resetTexture = this.resetTexture.bind(this);
         this.resizeTexture = this.resizeTexture.bind(this);
         this.uploadTexture = this.uploadTexture.bind(this);
-
+        this.setPickerOpen = this.setPickerOpen.bind(this);
+        this.onPointerDown = this.onPointerDown.bind(this);
     }
 
     componentDidMount() {
@@ -252,10 +256,18 @@ export class TextureEditorComponent extends React.Component<ITextureEditorCompon
         this._textureCanvasManager.metadata = data;
     }
 
+    setPickerOpen(open: boolean) {
+        this.setState({pickerOpen: open});
+    }
+
+    onPointerDown(evt: React.PointerEvent) {
+        if (!this._pickerRef.current?.contains(evt.target as Node)) {
+            this.setPickerOpen(false);
+        }
+    }
+
     saveTexture() {
-        Tools.ToBlob(this._2DCanvas.current!, (blob) => {
-            Tools.Download(blob!, this.props.url);
-        });
+        this._textureCanvasManager.saveTexture();
     }
 
     resetTexture() {
@@ -272,7 +284,8 @@ export class TextureEditorComponent extends React.Component<ITextureEditorCompon
 
     render() {
         const currentTool : ITool | undefined = this.state.tools[this.state.activeToolIndex];
-        return <div id="texture-editor">
+
+        return <div id="texture-editor" onPointerDown={this.onPointerDown}>
             <PropertiesBar
                 texture={this.props.texture}
                 saveTexture={this.saveTexture}
@@ -284,6 +297,7 @@ export class TextureEditorComponent extends React.Component<ITextureEditorCompon
                 uploadTexture={this.uploadTexture}
                 mipLevel={this.state.mipLevel}
                 setMipLevel={mipLevel => this.setState({mipLevel})}
+                size={this._textureCanvasManager?.size || this.props.texture.getSize()}
             />
             {!this.props.texture.isCube && <ToolBar
                 tools={this.state.tools}
@@ -292,6 +306,10 @@ export class TextureEditorComponent extends React.Component<ITextureEditorCompon
                 changeTool={this.changeTool}
                 metadata={this.state.metadata}
                 setMetadata={this.setMetadata}
+                pickerOpen={this.state.pickerOpen}
+                setPickerOpen={this.setPickerOpen}
+                pickerRef={this._pickerRef}
+                hasAlpha={this.props.texture.hasAlpha}
             />}
             <ChannelsBar channels={this.state.channels} setChannels={(channels) => {this.setState({channels})}}/>
             <TextureCanvasComponent canvas2D={this._2DCanvas} canvas3D={this._3DCanvas} canvasUI={this._UICanvas} texture={this.props.texture}/>

+ 18 - 37
inspector/src/components/actionTabs/tabs/propertyGrids/materials/textures/toolBar.tsx

@@ -13,27 +13,24 @@ interface IToolBarProps {
     activeToolIndex : number;
     metadata: IMetadata;
     setMetadata(data : any): void;
+    pickerOpen: boolean;
+    setPickerOpen(open: boolean): void;
+    pickerRef: React.RefObject<HTMLDivElement>;
+    hasAlpha: boolean;
 }
 
 interface IToolBarState {
     toolURL : string;
-    pickerOpen : boolean;
     addOpen : boolean;
 }
 
-
 export class ToolBar extends React.Component<IToolBarProps, IToolBarState> {
-    private _addTool = require('./assets/addTool.svg');
-
-    private _pickerRef : React.RefObject<HTMLDivElement>;
     constructor(props : IToolBarProps) {
         super(props);
         this.state = {
             toolURL: "",
-            pickerOpen: false,
             addOpen: false
         };
-        this._pickerRef = React.createRef();
     }
 
     computeRGBAColor() {
@@ -41,6 +38,10 @@ export class ToolBar extends React.Component<IToolBarProps, IToolBarState> {
         const opacityHex = opacityInt.toString(16).padStart(2, '0');
         return `${this.props.metadata.color}${opacityHex}`;
     }
+    
+    shouldComponentUpdate(nextProps: IToolBarProps) {
+        return (nextProps.tools != this.props.tools || nextProps.activeToolIndex !== this.props.activeToolIndex || nextProps.metadata != this.props.metadata || nextProps.pickerOpen != this.props.pickerOpen);
+    }
 
     render() {
         return <div id='toolbar'>
@@ -61,42 +62,22 @@ export class ToolBar extends React.Component<IToolBarProps, IToolBarState> {
                         />
                     }
                 )}
-                <div id='add-tool'>
-                    <img src={this._addTool} className='icon button' title='Add Tool' alt='Add Tool' onClick={() => this.setState({addOpen: !this.state.addOpen})}/>
-                    { this.state.addOpen && 
-                    <div id='add-tool-popup'>
-                        <form onSubmit={event => {
-                            event.preventDefault();
-                            this.props.addTool(this.state.toolURL);
-                            this.setState({toolURL: '', addOpen: false})
-                        }}>
-                            <label>
-                                Enter tool URL: <input value={this.state.toolURL} onChange={evt => this.setState({toolURL: evt.target.value})} type='text'/>
-                            </label>
-                            <button>Add</button>
-                        </form>
-                    </div> }
-                </div>
             </div>
-            <div id='color' onClick={() => this.setState({pickerOpen: !this.state.pickerOpen})} title='Color' className={`icon button${this.state.pickerOpen ? ` active` : ``}`}>
+            <div
+                id='color'
+                onClick={() => {if (!this.props.pickerOpen) this.props.setPickerOpen(true);}}
+                title='Color'
+                className={`icon button${this.props.pickerOpen ? ` active` : ``}`}
+            >
                 <div id='active-color-bg'>
                     <div id='active-color' style={{backgroundColor: this.props.metadata.color, opacity: this.props.metadata.alpha}}></div>
                 </div>
             </div>
             {
-                this.state.pickerOpen &&
-                <>
-                    <div className='color-picker-cover' onClick={evt => {
-                        if (evt.target !== this._pickerRef.current?.ownerDocument.querySelector('.color-picker-cover')) {
-                            return;
-                        }
-                        this.setState({pickerOpen: false});
-                    }}>
-                    </div>
-                    <div className='color-picker' ref={this._pickerRef}>
-                            <SketchPicker color={this.computeRGBAColor()}  onChange={color => this.props.setMetadata({color: color.hex, alpha: color.rgb.a})}/>
-                    </div>
-                </>
+                this.props.pickerOpen &&
+                <div id='color-picker' ref={this.props.pickerRef}>
+                    <SketchPicker disableAlpha={!this.props.hasAlpha} color={this.computeRGBAColor()}  onChange={color => this.props.setMetadata({color: color.hex, alpha: color.rgb.a})}/>
+                </div>
             }
         </div>;
     }

+ 5 - 2
inspector/src/inspector.ts

@@ -27,7 +27,7 @@ export class Inspector {
     private static _SceneExplorerHost: Nullable<HTMLElement>;
     private static _ActionTabsHost: Nullable<HTMLElement>;
     private static _EmbedHost: Nullable<HTMLElement>;
-    private static _NewCanvasContainer: HTMLElement;
+    private static _NewCanvasContainer: Nullable<HTMLElement>;
 
     private static _SceneExplorerWindow: Window;
     private static _ActionTabsWindow: Window;
@@ -471,6 +471,9 @@ export class Inspector {
     }
 
     private static _DestroyCanvasContainer() {
+        if (!this._NewCanvasContainer) {
+            return;
+        }
         const parentControl = this._NewCanvasContainer.parentElement!;
 
         while (this._NewCanvasContainer.childElementCount > 0) {
@@ -481,7 +484,7 @@ export class Inspector {
 
         parentControl.removeChild(this._NewCanvasContainer);
         parentControl.style.display = this._NewCanvasContainer.style.display;
-        delete this._NewCanvasContainer;
+        this._NewCanvasContainer = null;
     }
 
     private static _Cleanup() {

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

@@ -45,7 +45,7 @@ export class EXT_lights_image_based implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
         delete this._lights;
     }
 

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

@@ -36,7 +36,7 @@ export class EXT_mesh_gpu_instancing implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -27,7 +27,7 @@ export class EXT_texture_webp implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -48,7 +48,7 @@ export class ExtrasAsMetadata implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose(): void {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -45,7 +45,7 @@ export class KHR_draco_mesh_compression implements IGLTFLoaderExtension {
     /** @hidden */
     public dispose(): void {
         delete this.dracoCompression;
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -39,7 +39,7 @@ export class KHR_lights implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
         delete this._lights;
     }
 

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

@@ -40,7 +40,7 @@ export class KHR_materials_clearcoat implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -44,7 +44,7 @@ export class KHR_materials_ior implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -39,7 +39,7 @@ export class KHR_materials_pbrSpecularGlossiness implements IGLTFLoaderExtension
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -41,7 +41,7 @@ export class KHR_materials_sheen implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -40,7 +40,7 @@ export class KHR_materials_specular implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -42,7 +42,7 @@ export class KHR_materials_transmission implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -38,7 +38,7 @@ export class KHR_materials_unlit implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

+ 2 - 2
loaders/src/glTF/2.0/Extensions/KHR_materials_variants.ts

@@ -47,7 +47,7 @@ export class KHR_materials_variants implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /**
@@ -194,7 +194,7 @@ export class KHR_materials_variants implements IGLTFLoaderExtension {
 
                     // For each mapping, look at the variants and make a new entry for them.
                     const variants = extensionMetadata.variants;
-                    for (const mapping of extension.mapping) {
+                    for (const mapping of extension.mappings) {
                         for (const variantIndex of mapping.variants) {
                             const variant = ArrayItem.Get(`${extensionContext}/mapping/${variantIndex}`, this._variants, variantIndex);
                             const material = ArrayItem.Get(`#/materials/`, this._loader.gltf.materials, mapping.material);

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

@@ -28,7 +28,7 @@ export class KHR_texture_basisu implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -33,7 +33,7 @@ export class KHR_texture_transform implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /** @hidden */

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

@@ -34,7 +34,7 @@ export class KHR_xmp implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     /**

+ 3 - 3
loaders/src/glTF/2.0/Extensions/MSFT_audio_emitter.ts

@@ -64,9 +64,9 @@ export class MSFT_audio_emitter implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
-        delete this._clips;
-        delete this._emitters;
+        (this._loader as any) = null;
+        (this._clips as any) = null;
+        (this._emitters as any) = null;
     }
 
     /** @hidden */

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

@@ -78,7 +78,7 @@ export class MSFT_lod implements IGLTFLoaderExtension {
 
     /** @hidden */
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
 
         this._nodeIndexLOD = null;
         this._nodeSignalLODs.length = 0;

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

@@ -21,7 +21,7 @@ export class MSFT_minecraftMesh implements IGLTFLoaderExtension {
     }
 
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {

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

@@ -21,7 +21,7 @@ export class MSFT_sRGBFactors implements IGLTFLoaderExtension {
     }
 
     public dispose() {
-        delete this._loader;
+        (this._loader as any) = null;
     }
 
     public loadMaterialPropertiesAsync(context: string, material: IMaterial, babylonMaterial: Material): Nullable<Promise<void>> {

+ 3 - 3
loaders/src/glTF/2.0/glTFLoader.ts

@@ -216,9 +216,9 @@ export class GLTFLoader implements IGLTFLoader {
             delete this._extensions[name];
         }
 
-        delete this._gltf;
-        delete this._babylonScene;
-        delete this._rootBabylonMesh;
+        (this._gltf as any) = null;
+        (this._babylonScene as any) = null;
+        (this._rootBabylonMesh as any) = null;
 
         this._parent.dispose();
     }

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

@@ -223,7 +223,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
         }
         
         // Block types used to create the menu from
-        const allBlocks = {
+        const allBlocks: any = {
             Custom_Frames: customFrameNames,
             Animation: ["BonesBlock", "MorphTargetsBlock"],
             Color_Management: ["ReplaceColorBlock", "PosterizeBlock", "GradientBlock", "DesaturateBlock"],

+ 2 - 2
package.json

@@ -104,7 +104,7 @@
         "tslib": ">=1.10.0",
         "tslint": "^6.1.2",
         "typedoc": "^0.17.7",
-        "typescript": "~3.9.5",
+        "typescript": "^4.0.2",
         "webpack": "~4.43.0",
         "webpack-bundle-analyzer": "^3.8.0",
         "webpack-cli": "^3.3.11",
@@ -113,4 +113,4 @@
         "xhr2": "^0.2.0",
         "xmlbuilder": "15.1.1"
     }
-}
+}

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

@@ -40,7 +40,7 @@ export class KHR_lights_punctual implements IGLTFExporterExtensionV2 {
 
     /** @hidden */
     public dispose() {
-        delete this._lights;
+        (this._lights as any) = null;
     }
 
     /** @hidden */

+ 14 - 1
serializers/src/glTF/2.0/glTFMaterialExporter.ts

@@ -536,7 +536,7 @@ export class _GLTFMaterialExporter {
                             else {
                                 reject("gltfMaterialExporter: Failed to get blob from image canvas!");
                             }
-                        });
+                        }, mimeType);
                     }
                 }
                 else {
@@ -1199,6 +1199,19 @@ export class _GLTFMaterialExporter {
                 }
                 const size = babylonTexture.getSize();
 
+                // Preserve texture mime type if defined
+                if ((babylonTexture as Texture).mimeType) {
+                    switch ((babylonTexture as Texture).mimeType) {
+                        case "image/jpeg":
+                            mimeType = ImageMimeType.JPEG;
+                            break;
+                        case "image/png":
+                            mimeType = ImageMimeType.PNG;
+                            break;
+                    }
+
+                }
+
                 return this._createBase64FromCanvasAsync(pixels, size.width, size.height, mimeType).then((base64Data) => {
                     const textureInfo = this._getTextureInfoFromBase64(base64Data, babylonTexture.name.replace(/\.\/|\/|\.\\|\\/g, "_"), mimeType, babylonTexture.coordinatesIndex, samplerIndex);
                     if (textureInfo) {

+ 2 - 1
src/Actions/action.ts

@@ -4,6 +4,7 @@ import { Color3, Color4 } from "../Maths/math.color";
 import { Condition } from "./condition";
 import { _TypeStore } from '../Misc/typeStore';
 import { AbstractActionManager } from './abstractActionManager';
+import { Nullable } from "../types";
 
 declare type Scene = import("../scene").Scene;
 declare type ActionManager = import("./actionManager").ActionManager;
@@ -54,7 +55,7 @@ export interface IAction {
      * Internal only - manager for action
      * @hidden
      */
-    _actionManager: AbstractActionManager;
+    _actionManager: Nullable<AbstractActionManager>;
 
     /**
      * Adds action to chain of actions, may be a DoNothingAction

+ 1 - 1
src/Actions/actionManager.ts

@@ -296,7 +296,7 @@ export class ActionManager extends AbstractActionManager {
             if (ActionManager.Triggers[action.trigger] === 0) {
                 delete ActionManager.Triggers[action.trigger];
             }
-            delete action._actionManager;
+            action._actionManager = null;
             return true;
         }
         return false;

+ 15 - 3
src/Bones/skeleton.ts

@@ -66,6 +66,9 @@ export class Skeleton implements IAnimatable {
     /** @hidden */
     public _hasWaitingData: Nullable<boolean> = null;
 
+    /** @hidden */
+    public _waitingOverrideMeshId: Nullable<string> = null;
+
     /**
      * Specifies if the skeleton should be serialized
      */
@@ -706,6 +709,7 @@ export class Skeleton implements IAnimatable {
         serializationObject.bones = [];
 
         serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;
+        serializationObject.overrideMeshId = this.overrideMesh?.id;
 
         for (var index = 0; index < this.bones.length; index++) {
             var bone = this.bones[index];
@@ -713,9 +717,11 @@ export class Skeleton implements IAnimatable {
 
             var serializedBone: any = {
                 parentBoneIndex: parent ? this.bones.indexOf(parent) : -1,
+                index: bone.getIndex(),
                 name: bone.name,
                 matrix: bone.getBaseMatrix().toArray(),
-                rest: bone.getRestPose().toArray()
+                rest: bone.getRestPose().toArray(),
+                linkedTransformNodeId: bone.getTransformNode()?.id
             };
 
             serializationObject.bones.push(serializedBone);
@@ -764,16 +770,22 @@ export class Skeleton implements IAnimatable {
 
         skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;
 
+        if (parsedSkeleton.overrideMeshId) {
+            skeleton._hasWaitingData = true;
+            skeleton._waitingOverrideMeshId = parsedSkeleton.overrideMeshId;
+        }
+
         let index: number;
         for (index = 0; index < parsedSkeleton.bones.length; index++) {
             var parsedBone = parsedSkeleton.bones[index];
-
+            var parsedBoneIndex = parsedSkeleton.bones[index].index;
             var parentBone = null;
             if (parsedBone.parentBoneIndex > -1) {
                 parentBone = skeleton.bones[parsedBone.parentBoneIndex];
             }
+
             var rest: Nullable<Matrix> = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;
-            var bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest);
+            var bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest, null, parsedBoneIndex);
 
             if (parsedBone.id !== undefined && parsedBone.id !== null) {
                 bone.id = parsedBone.id;

+ 0 - 3
src/Cameras/arcRotateCamera.ts

@@ -76,9 +76,6 @@ export class ArcRotateCamera extends TargetCamera {
         this.setPosition(newPosition);
     }
 
-    @serializeAsVector3("upVector")
-    protected _upVector = Vector3.Up();
-
     protected _upToYMatrix: Matrix;
     protected _YToUpMatrix: Matrix;
 

+ 10 - 2
src/Cameras/camera.ts

@@ -119,12 +119,20 @@ export class Camera extends Node {
         this._position = newPosition;
     }
 
+    @serializeAsVector3("upVector")
+    protected _upVector = Vector3.Up();
+
     /**
      * The vector the camera should consider as up.
      * (default is Vector3(0, 1, 0) aka Vector3.Up())
      */
-    @serializeAsVector3()
-    public upVector = Vector3.Up();
+    public set upVector(vec: Vector3) {
+        this._upVector = vec;
+    }
+
+    public get upVector() {
+        return this._upVector;
+    }
 
     /**
      * Define the current limit on the left side for an orthographic camera

+ 6 - 9
src/Debug/axesViewer.ts

@@ -19,7 +19,7 @@ export class AxesViewer {
     /**
      * Gets the hosting scene
      */
-    public scene: Scene;
+    public scene: Nullable<Scene> = null;
 
     /**
      * Gets or sets a number used to scale line length
@@ -117,10 +117,10 @@ export class AxesViewer {
      * @returns a new axes viewer with instanced meshes
      */
     public createInstance(): AxesViewer {
-        const xAxis = AxisDragGizmo._CreateArrowInstance(this.scene, this._xAxis);
-        const yAxis = AxisDragGizmo._CreateArrowInstance(this.scene, this._yAxis);
-        const zAxis = AxisDragGizmo._CreateArrowInstance(this.scene, this._zAxis);
-        const axesViewer = new AxesViewer(this.scene, this.scaleLines, null, xAxis, yAxis, zAxis);
+        const xAxis = AxisDragGizmo._CreateArrowInstance(this.scene!, this._xAxis);
+        const yAxis = AxisDragGizmo._CreateArrowInstance(this.scene!, this._yAxis);
+        const zAxis = AxisDragGizmo._CreateArrowInstance(this.scene!, this._zAxis);
+        const axesViewer = new AxesViewer(this.scene!, this.scaleLines, null, xAxis, yAxis, zAxis);
         axesViewer._instanced = true;
         return axesViewer;
     }
@@ -129,20 +129,17 @@ export class AxesViewer {
     public dispose() {
         if (this._xAxis) {
             this._xAxis.dispose(false, !this._instanced);
-            delete this._xAxis;
         }
 
         if (this._yAxis) {
             this._yAxis.dispose(false, !this._instanced);
-            delete this._yAxis;
         }
 
         if (this._zAxis) {
             this._zAxis.dispose(false, !this._instanced);
-            delete this._zAxis;
         }
 
-        delete this.scene;
+        this.scene = null;
     }
 
     private static _SetRenderingGroupId(node: TransformNode, id: number) {

+ 0 - 0
src/Engines/Extensions/engine.textureSelector.ts


Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä