ソースを参照

Merge pull request #8232 from BabylonJS/master

Nightly
David Catuhe 5 年 前
コミット
d4a1461cda
53 ファイル変更1062 行追加583 行削除
  1. 25 28
      dist/preview release/babylon.d.ts
  2. 1 1
      dist/preview release/babylon.js
  3. 190 205
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 55 59
      dist/preview release/babylon.module.d.ts
  6. 29 28
      dist/preview release/documentation.d.ts
  7. 4 0
      dist/preview release/gui/babylon.gui.d.ts
  8. 2 2
      dist/preview release/gui/babylon.gui.js
  9. 1 1
      dist/preview release/gui/babylon.gui.js.map
  10. 2 2
      dist/preview release/gui/babylon.gui.min.js
  11. 8 0
      dist/preview release/gui/babylon.gui.module.d.ts
  12. 6 6
      dist/preview release/inspector/babylon.inspector.bundle.js
  13. 230 46
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  14. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  15. 11 0
      dist/preview release/inspector/babylon.inspector.d.ts
  16. 22 0
      dist/preview release/inspector/babylon.inspector.module.d.ts
  17. 1 1
      dist/preview release/packagesSizeBaseLine.json
  18. 8 1
      dist/preview release/serializers/babylon.objSerializer.js
  19. 1 1
      dist/preview release/serializers/babylon.objSerializer.js.map
  20. 1 1
      dist/preview release/serializers/babylon.objSerializer.min.js
  21. 8 1
      dist/preview release/serializers/babylonjs.serializers.js
  22. 1 1
      dist/preview release/serializers/babylonjs.serializers.js.map
  23. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  24. 55 59
      dist/preview release/viewer/babylon.module.d.ts
  25. 15 15
      dist/preview release/viewer/babylon.viewer.js
  26. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  27. 7 0
      dist/preview release/what's new.md
  28. 6 1
      gui/src/2D/controls/textBlock.ts
  29. 1 1
      gui/src/3D/controls/control3D.ts
  30. 3 2
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/anchorSvgPoint.tsx
  31. 210 23
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent.tsx
  32. 21 1
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/curveEditor.scss
  33. 9 1
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/graphActionsBar.tsx
  34. 2 2
      inspector/src/components/actionTabs/tabs/propertyGrids/animations/keyframeSvgPoint.tsx
  35. 1 1
      inspector/src/components/actionTabs/tabs/propertyGrids/commonPropertyGridComponent.tsx
  36. 7 1
      serializers/src/OBJ/objSerializer.ts
  37. 1 1
      src/DeviceInput/InputDevices/deviceSourceManager.ts
  38. 18 5
      src/DeviceInput/deviceInputSystem.ts
  39. 2 2
      src/Layers/effectLayer.ts
  40. 6 4
      src/Lights/Shadows/shadowGenerator.ts
  41. 35 15
      src/Materials/material.ts
  42. 2 2
      src/Materials/multiMaterial.ts
  43. 2 2
      src/Materials/shaderMaterial.ts
  44. 1 0
      src/Meshes/index.ts
  45. 20 8
      src/Meshes/subMesh.ts
  46. 0 5
      src/Meshes/thinInstanceMesh.ts
  47. 12 25
      src/Particles/EmitterTypes/coneParticleEmitter.ts
  48. 2 0
      src/Particles/index.ts
  49. 0 5
      src/Particles/particleSystemComponent.ts
  50. 2 4
      src/PostProcesses/volumetricLightScatteringPostProcess.ts
  51. 2 4
      src/Rendering/depthRenderer.ts
  52. 2 4
      src/Rendering/geometryBufferRenderer.ts
  53. 8 2
      src/XR/features/WebXRControllerPointerSelection.ts

+ 25 - 28
dist/preview release/babylon.d.ts

@@ -16583,7 +16583,7 @@ declare module BABYLON {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Checks if the material is ready to render the requested mesh
          * @param mesh Define the mesh to render
@@ -24057,7 +24057,7 @@ declare module BABYLON {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Returns the material effect
          * @returns the effect associated with the material
@@ -24342,7 +24342,7 @@ declare module BABYLON {
          * @param useInstances Define whether or not the material is used with instances
          * @returns true if ready, otherwise false
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Clones the current material and its related sub materials
          * @param name Define the name of the newly cloned material
@@ -24373,9 +24373,19 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Base class for submeshes
+     * Defines a subdivision inside a mesh
      */
-    export class BaseSubMesh {
+    export class SubMesh implements ICullable {
+        /** the material index to use */
+        materialIndex: number;
+        /** vertex index start */
+        verticesStart: number;
+        /** vertices count */
+        verticesCount: number;
+        /** index start */
+        indexStart: number;
+        /** indices count */
+        indexCount: number;
         /** @hidden */
         _materialDefines: Nullable<MaterialDefines>;
         /** @hidden */
@@ -24400,21 +24410,6 @@ declare module BABYLON {
          * @param defines defines the set of defines used to compile this effect
          */
         setEffect(effect: Nullable<Effect>, defines?: Nullable<MaterialDefines>): void;
-    }
-    /**
-     * Defines a subdivision inside a mesh
-     */
-    export class SubMesh extends BaseSubMesh implements ICullable {
-        /** the material index to use */
-        materialIndex: number;
-        /** vertex index start */
-        verticesStart: number;
-        /** vertices count */
-        verticesCount: number;
-        /** index start */
-        indexStart: number;
-        /** indices count */
-        indexCount: number;
         /** @hidden */
         _linesIndexCount: number;
         private _mesh;
@@ -24498,6 +24493,16 @@ declare module BABYLON {
          */
         getRenderingMesh(): Mesh;
         /**
+         * Returns the replacement mesh of the submesh
+         * @returns the replacement mesh (could be different from parent mesh)
+         */
+        getReplacementMesh(): Nullable<AbstractMesh>;
+        /**
+         * Returns the effective mesh of the submesh
+         * @returns the effective mesh (could be different from parent mesh)
+         */
+        getEffectiveMesh(): AbstractMesh;
+        /**
          * Returns the submesh material
          * @returns null or the current material
          */
@@ -64999,10 +65004,6 @@ declare module BABYLON {
                 };
             };
         }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild2: number;
 }
 declare module BABYLON {
     /**
@@ -66224,10 +66225,6 @@ declare module BABYLON {
              */
             getHierarchyEmittedParticleSystems(): IParticleSystem[];
         }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild: number;
 }
 declare module BABYLON {
     /** Defines the 4 color options */

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/babylon.js


ファイルの差分が大きいため隠しています
+ 190 - 205
dist/preview release/babylon.max.js


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/babylon.max.js.map


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

@@ -16756,7 +16756,7 @@ declare module "babylonjs/Materials/shaderMaterial" {
     import { Matrix, Vector3, Vector2, Vector4 } from "babylonjs/Maths/math.vector";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Mesh } from "babylonjs/Meshes/mesh";
-    import { SubMesh, BaseSubMesh } from "babylonjs/Meshes/subMesh";
+    import { SubMesh } from "babylonjs/Meshes/subMesh";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
     import { Effect } from "babylonjs/Materials/effect";
     import { Material } from "babylonjs/Materials/material";
@@ -17016,7 +17016,7 @@ declare module "babylonjs/Materials/shaderMaterial" {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Checks if the material is ready to render the requested mesh
          * @param mesh Define the mesh to render
@@ -24459,7 +24459,7 @@ declare module "babylonjs/Materials/material" {
     import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
     import { Matrix } from "babylonjs/Maths/math.vector";
-    import { BaseSubMesh, SubMesh } from "babylonjs/Meshes/subMesh";
+    import { SubMesh } from "babylonjs/Meshes/subMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { UniformBuffer } from "babylonjs/Materials/uniformBuffer";
     import { Effect } from "babylonjs/Materials/effect";
@@ -24906,7 +24906,7 @@ declare module "babylonjs/Materials/material" {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Returns the material effect
          * @returns the effect associated with the material
@@ -25142,7 +25142,7 @@ declare module "babylonjs/Materials/multiMaterial" {
     import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
-    import { BaseSubMesh } from "babylonjs/Meshes/subMesh";
+    import { SubMesh } from "babylonjs/Meshes/subMesh";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
     import { Material } from "babylonjs/Materials/material";
     /**
@@ -25197,7 +25197,7 @@ declare module "babylonjs/Materials/multiMaterial" {
          * @param useInstances Define whether or not the material is used with instances
          * @returns true if ready, otherwise false
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Clones the current material and its related sub materials
          * @param name Define the name of the newly cloned material
@@ -25243,9 +25243,19 @@ declare module "babylonjs/Meshes/subMesh" {
     import { Ray } from "babylonjs/Culling/ray";
     import { TrianglePickingPredicate } from "babylonjs/Culling/ray";
     /**
-     * Base class for submeshes
+     * Defines a subdivision inside a mesh
      */
-    export class BaseSubMesh {
+    export class SubMesh implements ICullable {
+        /** the material index to use */
+        materialIndex: number;
+        /** vertex index start */
+        verticesStart: number;
+        /** vertices count */
+        verticesCount: number;
+        /** index start */
+        indexStart: number;
+        /** indices count */
+        indexCount: number;
         /** @hidden */
         _materialDefines: Nullable<MaterialDefines>;
         /** @hidden */
@@ -25270,21 +25280,6 @@ declare module "babylonjs/Meshes/subMesh" {
          * @param defines defines the set of defines used to compile this effect
          */
         setEffect(effect: Nullable<Effect>, defines?: Nullable<MaterialDefines>): void;
-    }
-    /**
-     * Defines a subdivision inside a mesh
-     */
-    export class SubMesh extends BaseSubMesh implements ICullable {
-        /** the material index to use */
-        materialIndex: number;
-        /** vertex index start */
-        verticesStart: number;
-        /** vertices count */
-        verticesCount: number;
-        /** index start */
-        indexStart: number;
-        /** indices count */
-        indexCount: number;
         /** @hidden */
         _linesIndexCount: number;
         private _mesh;
@@ -25368,6 +25363,16 @@ declare module "babylonjs/Meshes/subMesh" {
          */
         getRenderingMesh(): Mesh;
         /**
+         * Returns the replacement mesh of the submesh
+         * @returns the replacement mesh (could be different from parent mesh)
+         */
+        getReplacementMesh(): Nullable<AbstractMesh>;
+        /**
+         * Returns the effective mesh of the submesh
+         * @returns the effective mesh (could be different from parent mesh)
+         */
+        getEffectiveMesh(): AbstractMesh;
+        /**
          * Returns the submesh material
          * @returns null or the current material
          */
@@ -68387,10 +68392,6 @@ declare module "babylonjs/Meshes/thinInstanceMesh" {
             };
         }
     }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild2: number;
 }
 declare module "babylonjs/Meshes/index" {
     export * from "babylonjs/Meshes/abstractMesh";
@@ -68414,6 +68415,7 @@ declare module "babylonjs/Meshes/index" {
     export * from "babylonjs/Meshes/Builders/index";
     export * from "babylonjs/Meshes/dataBuffer";
     export * from "babylonjs/Meshes/WebGL/webGLDataBuffer";
+    import "babylonjs/Meshes/thinInstanceMesh";
     export * from "babylonjs/Meshes/thinInstanceMesh";
 }
 declare module "babylonjs/Morph/index" {
@@ -69702,10 +69704,6 @@ declare module "babylonjs/Particles/particleSystemComponent" {
             getHierarchyEmittedParticleSystems(): IParticleSystem[];
         }
     }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild: number;
 }
 declare module "babylonjs/Particles/pointsCloudSystem" {
     import { Color4 } from "babylonjs/Maths/math";
@@ -70141,6 +70139,7 @@ declare module "babylonjs/Particles/index" {
     export * from "babylonjs/Particles/particle";
     export * from "babylonjs/Particles/particleHelper";
     export * from "babylonjs/Particles/particleSystem";
+    import "babylonjs/Particles/particleSystemComponent";
     export * from "babylonjs/Particles/particleSystemComponent";
     export * from "babylonjs/Particles/particleSystemSet";
     export * from "babylonjs/Particles/solidParticle";
@@ -93747,7 +93746,7 @@ declare module BABYLON {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Checks if the material is ready to render the requested mesh
          * @param mesh Define the mesh to render
@@ -101221,7 +101220,7 @@ declare module BABYLON {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Returns the material effect
          * @returns the effect associated with the material
@@ -101506,7 +101505,7 @@ declare module BABYLON {
          * @param useInstances Define whether or not the material is used with instances
          * @returns true if ready, otherwise false
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Clones the current material and its related sub materials
          * @param name Define the name of the newly cloned material
@@ -101537,9 +101536,19 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Base class for submeshes
+     * Defines a subdivision inside a mesh
      */
-    export class BaseSubMesh {
+    export class SubMesh implements ICullable {
+        /** the material index to use */
+        materialIndex: number;
+        /** vertex index start */
+        verticesStart: number;
+        /** vertices count */
+        verticesCount: number;
+        /** index start */
+        indexStart: number;
+        /** indices count */
+        indexCount: number;
         /** @hidden */
         _materialDefines: Nullable<MaterialDefines>;
         /** @hidden */
@@ -101564,21 +101573,6 @@ declare module BABYLON {
          * @param defines defines the set of defines used to compile this effect
          */
         setEffect(effect: Nullable<Effect>, defines?: Nullable<MaterialDefines>): void;
-    }
-    /**
-     * Defines a subdivision inside a mesh
-     */
-    export class SubMesh extends BaseSubMesh implements ICullable {
-        /** the material index to use */
-        materialIndex: number;
-        /** vertex index start */
-        verticesStart: number;
-        /** vertices count */
-        verticesCount: number;
-        /** index start */
-        indexStart: number;
-        /** indices count */
-        indexCount: number;
         /** @hidden */
         _linesIndexCount: number;
         private _mesh;
@@ -101662,6 +101656,16 @@ declare module BABYLON {
          */
         getRenderingMesh(): Mesh;
         /**
+         * Returns the replacement mesh of the submesh
+         * @returns the replacement mesh (could be different from parent mesh)
+         */
+        getReplacementMesh(): Nullable<AbstractMesh>;
+        /**
+         * Returns the effective mesh of the submesh
+         * @returns the effective mesh (could be different from parent mesh)
+         */
+        getEffectiveMesh(): AbstractMesh;
+        /**
          * Returns the submesh material
          * @returns null or the current material
          */
@@ -142163,10 +142167,6 @@ declare module BABYLON {
                 };
             };
         }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild2: number;
 }
 declare module BABYLON {
     /**
@@ -143388,10 +143388,6 @@ declare module BABYLON {
              */
             getHierarchyEmittedParticleSystems(): IParticleSystem[];
         }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild: number;
 }
 declare module BABYLON {
     /** Defines the 4 color options */

+ 29 - 28
dist/preview release/documentation.d.ts

@@ -16583,7 +16583,7 @@ declare module BABYLON {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Checks if the material is ready to render the requested mesh
          * @param mesh Define the mesh to render
@@ -24057,7 +24057,7 @@ declare module BABYLON {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Returns the material effect
          * @returns the effect associated with the material
@@ -24342,7 +24342,7 @@ declare module BABYLON {
          * @param useInstances Define whether or not the material is used with instances
          * @returns true if ready, otherwise false
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Clones the current material and its related sub materials
          * @param name Define the name of the newly cloned material
@@ -24373,9 +24373,19 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Base class for submeshes
+     * Defines a subdivision inside a mesh
      */
-    export class BaseSubMesh {
+    export class SubMesh implements ICullable {
+        /** the material index to use */
+        materialIndex: number;
+        /** vertex index start */
+        verticesStart: number;
+        /** vertices count */
+        verticesCount: number;
+        /** index start */
+        indexStart: number;
+        /** indices count */
+        indexCount: number;
         /** @hidden */
         _materialDefines: Nullable<MaterialDefines>;
         /** @hidden */
@@ -24400,21 +24410,6 @@ declare module BABYLON {
          * @param defines defines the set of defines used to compile this effect
          */
         setEffect(effect: Nullable<Effect>, defines?: Nullable<MaterialDefines>): void;
-    }
-    /**
-     * Defines a subdivision inside a mesh
-     */
-    export class SubMesh extends BaseSubMesh implements ICullable {
-        /** the material index to use */
-        materialIndex: number;
-        /** vertex index start */
-        verticesStart: number;
-        /** vertices count */
-        verticesCount: number;
-        /** index start */
-        indexStart: number;
-        /** indices count */
-        indexCount: number;
         /** @hidden */
         _linesIndexCount: number;
         private _mesh;
@@ -24498,6 +24493,16 @@ declare module BABYLON {
          */
         getRenderingMesh(): Mesh;
         /**
+         * Returns the replacement mesh of the submesh
+         * @returns the replacement mesh (could be different from parent mesh)
+         */
+        getReplacementMesh(): Nullable<AbstractMesh>;
+        /**
+         * Returns the effective mesh of the submesh
+         * @returns the effective mesh (could be different from parent mesh)
+         */
+        getEffectiveMesh(): AbstractMesh;
+        /**
          * Returns the submesh material
          * @returns null or the current material
          */
@@ -64999,10 +65004,6 @@ declare module BABYLON {
                 };
             };
         }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild2: number;
 }
 declare module BABYLON {
     /**
@@ -66224,10 +66225,6 @@ declare module BABYLON {
              */
             getHierarchyEmittedParticleSystems(): IParticleSystem[];
         }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild: number;
 }
 declare module BABYLON {
     /** Defines the 4 color options */
@@ -75202,6 +75199,10 @@ declare module BABYLON.GUI {
         */
         onLinesReadyObservable: BABYLON.Observable<TextBlock>;
         /**
+         * Function used to split a string into words. By default, a string is split at each space character found
+         */
+        wordSplittingFunction: BABYLON.Nullable<(line: string) => string[]>;
+        /**
          * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
          */
         get lines(): any[];

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

@@ -1425,6 +1425,10 @@ declare module BABYLON.GUI {
         */
         onLinesReadyObservable: BABYLON.Observable<TextBlock>;
         /**
+         * Function used to split a string into words. By default, a string is split at each space character found
+         */
+        wordSplittingFunction: BABYLON.Nullable<(line: string) => string[]>;
+        /**
          * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
          */
         get lines(): any[];

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

@@ -12722,7 +12722,7 @@ var TextBlock = /** @class */ (function (_super) {
     TextBlock.prototype._parseLineWordWrap = function (line, width, context) {
         if (line === void 0) { line = ''; }
         var lines = [];
-        var words = line.split(' ');
+        var words = this.wordSplittingFunction ? this.wordSplittingFunction(line) : line.split(' ');
         var lineWidth = 0;
         for (var n = 0; n < words.length; n++) {
             var testLine = n > 0 ? line + " " + words[n] : words[0];
@@ -15090,7 +15090,7 @@ var Control3D = /** @class */ (function () {
             this._host._lastPickedControl = this;
             return true;
         }
-        if (type === babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERUP) {
+        if (type === babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERUP || type === babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["PointerEventTypes"].POINTERDOUBLETAP) {
             if (this._host._lastControlDown[pointerId]) {
                 this._host._lastControlDown[pointerId]._onPointerUp(this, pickedPoint, pointerId, buttonIndex, true);
             }

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/gui/babylon.gui.js.map


ファイルの差分が大きいため隠しています
+ 2 - 2
dist/preview release/gui/babylon.gui.min.js


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

@@ -1466,6 +1466,10 @@ declare module "babylonjs-gui/2D/controls/textBlock" {
         */
         onLinesReadyObservable: Observable<TextBlock>;
         /**
+         * Function used to split a string into words. By default, a string is split at each space character found
+         */
+        wordSplittingFunction: Nullable<(line: string) => string[]>;
+        /**
          * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
          */
         get lines(): any[];
@@ -5800,6 +5804,10 @@ declare module BABYLON.GUI {
         */
         onLinesReadyObservable: BABYLON.Observable<TextBlock>;
         /**
+         * Function used to split a string into words. By default, a string is split at each space character found
+         */
+        wordSplittingFunction: BABYLON.Nullable<(line: string) => string[]>;
+        /**
          * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
          */
         get lines(): any[];

ファイルの差分が大きいため隠しています
+ 6 - 6
dist/preview release/inspector/babylon.inspector.bundle.js


ファイルの差分が大きいため隠しています
+ 230 - 46
dist/preview release/inspector/babylon.inspector.bundle.max.js


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 11 - 0
dist/preview release/inspector/babylon.inspector.d.ts

@@ -518,6 +518,7 @@ declare module INSPECTOR {
         active: boolean;
         type: string;
         index: string;
+        selected: boolean;
     }
     export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps> {
         constructor(props: IAnchorSvgPointProps);
@@ -620,9 +621,12 @@ declare module INSPECTOR {
 declare module INSPECTOR {
     interface IGraphActionsBarProps {
         addKeyframe: () => void;
+        removeKeyframe: () => void;
         handleValueChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
+        handleFrameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
         flatTangent: () => void;
         currentValue: number;
+        currentFrame: number;
     }
     export class GraphActionsBar extends React.Component<IGraphActionsBarProps> {
         constructor(props: IGraphActionsBarProps);
@@ -660,6 +664,9 @@ declare module INSPECTOR {
         scale: number;
         playheadOffset: number;
         notification: string;
+        currentPoint: SVGPoint | undefined;
+        lastFrame: number;
+        playheadPos: number;
     }> {
         private _heightScale;
         readonly _canvasLength: number;
@@ -668,6 +675,8 @@ declare module INSPECTOR {
         private _frames;
         private _isPlaying;
         private _graphCanvas;
+        private _selectedCurve;
+        private _svgCanvas;
         constructor(props: IAnimationCurveEditorComponentProps);
         componentDidMount(): void;
         resetPlayheadOffset(): void;
@@ -675,11 +684,13 @@ declare module INSPECTOR {
         getValueLabel(i: number): number;
         handleNameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleTypeChange(event: React.ChangeEvent<HTMLSelectElement>): void;
         handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>): void;
         addAnimation(): void;
         clearNotification(): void;
         addKeyframeClick(): void;
+        removeKeyframeClick(): void;
         addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
         updateKeyframe(keyframe: BABYLON.Vector2, index: number): void;
         getAnimationProperties(animation: BABYLON.Animation): {

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

@@ -589,6 +589,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         active: boolean;
         type: string;
         index: string;
+        selected: boolean;
     }
     export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps> {
         constructor(props: IAnchorSvgPointProps);
@@ -701,9 +702,12 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
     import * as React from "react";
     interface IGraphActionsBarProps {
         addKeyframe: () => void;
+        removeKeyframe: () => void;
         handleValueChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
+        handleFrameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
         flatTangent: () => void;
         currentValue: number;
+        currentFrame: number;
     }
     export class GraphActionsBar extends React.Component<IGraphActionsBarProps> {
         constructor(props: IGraphActionsBarProps);
@@ -749,6 +753,9 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         scale: number;
         playheadOffset: number;
         notification: string;
+        currentPoint: SVGPoint | undefined;
+        lastFrame: number;
+        playheadPos: number;
     }> {
         private _heightScale;
         readonly _canvasLength: number;
@@ -757,6 +764,8 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         private _frames;
         private _isPlaying;
         private _graphCanvas;
+        private _selectedCurve;
+        private _svgCanvas;
         constructor(props: IAnimationCurveEditorComponentProps);
         componentDidMount(): void;
         resetPlayheadOffset(): void;
@@ -764,11 +773,13 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         getValueLabel(i: number): number;
         handleNameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleTypeChange(event: React.ChangeEvent<HTMLSelectElement>): void;
         handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>): void;
         addAnimation(): void;
         clearNotification(): void;
         addKeyframeClick(): void;
+        removeKeyframeClick(): void;
         addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
         updateKeyframe(keyframe: Vector2, index: number): void;
         getAnimationProperties(animation: Animation): {
@@ -3681,6 +3692,7 @@ declare module INSPECTOR {
         active: boolean;
         type: string;
         index: string;
+        selected: boolean;
     }
     export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps> {
         constructor(props: IAnchorSvgPointProps);
@@ -3783,9 +3795,12 @@ declare module INSPECTOR {
 declare module INSPECTOR {
     interface IGraphActionsBarProps {
         addKeyframe: () => void;
+        removeKeyframe: () => void;
         handleValueChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
+        handleFrameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
         flatTangent: () => void;
         currentValue: number;
+        currentFrame: number;
     }
     export class GraphActionsBar extends React.Component<IGraphActionsBarProps> {
         constructor(props: IGraphActionsBarProps);
@@ -3823,6 +3838,9 @@ declare module INSPECTOR {
         scale: number;
         playheadOffset: number;
         notification: string;
+        currentPoint: SVGPoint | undefined;
+        lastFrame: number;
+        playheadPos: number;
     }> {
         private _heightScale;
         readonly _canvasLength: number;
@@ -3831,6 +3849,8 @@ declare module INSPECTOR {
         private _frames;
         private _isPlaying;
         private _graphCanvas;
+        private _selectedCurve;
+        private _svgCanvas;
         constructor(props: IAnimationCurveEditorComponentProps);
         componentDidMount(): void;
         resetPlayheadOffset(): void;
@@ -3838,11 +3858,13 @@ declare module INSPECTOR {
         getValueLabel(i: number): number;
         handleNameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleValueChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        handleFrameChange(event: React.ChangeEvent<HTMLInputElement>): void;
         handleTypeChange(event: React.ChangeEvent<HTMLSelectElement>): void;
         handlePropertyChange(event: React.ChangeEvent<HTMLInputElement>): void;
         addAnimation(): void;
         clearNotification(): void;
         addKeyframeClick(): void;
+        removeKeyframeClick(): void;
         addKeyFrame(event: React.MouseEvent<SVGSVGElement>): void;
         updateKeyframe(keyframe: BABYLON.Vector2, index: number): void;
         getAnimationProperties(animation: BABYLON.Animation): {

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

@@ -1 +1 @@
-{"thinEngineOnly":115966,"engineOnly":152369,"sceneOnly":511651,"minGridMaterial":647502,"minStandardMaterial":791615}
+{"thinEngineOnly":115966,"engineOnly":152369,"sceneOnly":505311,"minGridMaterial":647903,"minStandardMaterial":792016}

+ 8 - 1
dist/preview release/serializers/babylon.objSerializer.js

@@ -214,7 +214,14 @@ var OBJExport = /** @class */ (function () {
                 continue;
             }
             for (var i = 0; i < trunkVerts.length; i += 3) {
-                output.push("v " + trunkVerts[i] + " " + trunkVerts[i + 1] + " " + trunkVerts[i + 2]);
+                // Babylon.js default is left handed, while OBJ default is right handed
+                // Need to invert Z vertices unless Babylon is set to use a right handed system
+                if (mesh[0].getScene().useRightHandedSystem) {
+                    output.push("v " + trunkVerts[i] + " " + trunkVerts[i + 1] + " " + trunkVerts[i + 2]);
+                }
+                else {
+                    output.push("v " + trunkVerts[i] + " " + trunkVerts[i + 1] + " " + -trunkVerts[i + 2]);
+                }
                 curV++;
             }
             if (trunkNormals != null) {

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/serializers/babylon.objSerializer.js.map


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/serializers/babylon.objSerializer.min.js


+ 8 - 1
dist/preview release/serializers/babylonjs.serializers.js

@@ -443,7 +443,14 @@ var OBJExport = /** @class */ (function () {
                 continue;
             }
             for (var i = 0; i < trunkVerts.length; i += 3) {
-                output.push("v " + trunkVerts[i] + " " + trunkVerts[i + 1] + " " + trunkVerts[i + 2]);
+                // Babylon.js default is left handed, while OBJ default is right handed
+                // Need to invert Z vertices unless Babylon is set to use a right handed system
+                if (mesh[0].getScene().useRightHandedSystem) {
+                    output.push("v " + trunkVerts[i] + " " + trunkVerts[i + 1] + " " + trunkVerts[i + 2]);
+                }
+                else {
+                    output.push("v " + trunkVerts[i] + " " + trunkVerts[i + 1] + " " + -trunkVerts[i + 2]);
+                }
                 curV++;
             }
             if (trunkNormals != null) {

ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.js.map


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


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

@@ -16756,7 +16756,7 @@ declare module "babylonjs/Materials/shaderMaterial" {
     import { Matrix, Vector3, Vector2, Vector4 } from "babylonjs/Maths/math.vector";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { Mesh } from "babylonjs/Meshes/mesh";
-    import { SubMesh, BaseSubMesh } from "babylonjs/Meshes/subMesh";
+    import { SubMesh } from "babylonjs/Meshes/subMesh";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
     import { Effect } from "babylonjs/Materials/effect";
     import { Material } from "babylonjs/Materials/material";
@@ -17016,7 +17016,7 @@ declare module "babylonjs/Materials/shaderMaterial" {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Checks if the material is ready to render the requested mesh
          * @param mesh Define the mesh to render
@@ -24459,7 +24459,7 @@ declare module "babylonjs/Materials/material" {
     import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
     import { Matrix } from "babylonjs/Maths/math.vector";
-    import { BaseSubMesh, SubMesh } from "babylonjs/Meshes/subMesh";
+    import { SubMesh } from "babylonjs/Meshes/subMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { UniformBuffer } from "babylonjs/Materials/uniformBuffer";
     import { Effect } from "babylonjs/Materials/effect";
@@ -24906,7 +24906,7 @@ declare module "babylonjs/Materials/material" {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Returns the material effect
          * @returns the effect associated with the material
@@ -25142,7 +25142,7 @@ declare module "babylonjs/Materials/multiMaterial" {
     import { Nullable } from "babylonjs/types";
     import { Scene } from "babylonjs/scene";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
-    import { BaseSubMesh } from "babylonjs/Meshes/subMesh";
+    import { SubMesh } from "babylonjs/Meshes/subMesh";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
     import { Material } from "babylonjs/Materials/material";
     /**
@@ -25197,7 +25197,7 @@ declare module "babylonjs/Materials/multiMaterial" {
          * @param useInstances Define whether or not the material is used with instances
          * @returns true if ready, otherwise false
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Clones the current material and its related sub materials
          * @param name Define the name of the newly cloned material
@@ -25243,9 +25243,19 @@ declare module "babylonjs/Meshes/subMesh" {
     import { Ray } from "babylonjs/Culling/ray";
     import { TrianglePickingPredicate } from "babylonjs/Culling/ray";
     /**
-     * Base class for submeshes
+     * Defines a subdivision inside a mesh
      */
-    export class BaseSubMesh {
+    export class SubMesh implements ICullable {
+        /** the material index to use */
+        materialIndex: number;
+        /** vertex index start */
+        verticesStart: number;
+        /** vertices count */
+        verticesCount: number;
+        /** index start */
+        indexStart: number;
+        /** indices count */
+        indexCount: number;
         /** @hidden */
         _materialDefines: Nullable<MaterialDefines>;
         /** @hidden */
@@ -25270,21 +25280,6 @@ declare module "babylonjs/Meshes/subMesh" {
          * @param defines defines the set of defines used to compile this effect
          */
         setEffect(effect: Nullable<Effect>, defines?: Nullable<MaterialDefines>): void;
-    }
-    /**
-     * Defines a subdivision inside a mesh
-     */
-    export class SubMesh extends BaseSubMesh implements ICullable {
-        /** the material index to use */
-        materialIndex: number;
-        /** vertex index start */
-        verticesStart: number;
-        /** vertices count */
-        verticesCount: number;
-        /** index start */
-        indexStart: number;
-        /** indices count */
-        indexCount: number;
         /** @hidden */
         _linesIndexCount: number;
         private _mesh;
@@ -25368,6 +25363,16 @@ declare module "babylonjs/Meshes/subMesh" {
          */
         getRenderingMesh(): Mesh;
         /**
+         * Returns the replacement mesh of the submesh
+         * @returns the replacement mesh (could be different from parent mesh)
+         */
+        getReplacementMesh(): Nullable<AbstractMesh>;
+        /**
+         * Returns the effective mesh of the submesh
+         * @returns the effective mesh (could be different from parent mesh)
+         */
+        getEffectiveMesh(): AbstractMesh;
+        /**
          * Returns the submesh material
          * @returns null or the current material
          */
@@ -68387,10 +68392,6 @@ declare module "babylonjs/Meshes/thinInstanceMesh" {
             };
         }
     }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild2: number;
 }
 declare module "babylonjs/Meshes/index" {
     export * from "babylonjs/Meshes/abstractMesh";
@@ -68414,6 +68415,7 @@ declare module "babylonjs/Meshes/index" {
     export * from "babylonjs/Meshes/Builders/index";
     export * from "babylonjs/Meshes/dataBuffer";
     export * from "babylonjs/Meshes/WebGL/webGLDataBuffer";
+    import "babylonjs/Meshes/thinInstanceMesh";
     export * from "babylonjs/Meshes/thinInstanceMesh";
 }
 declare module "babylonjs/Morph/index" {
@@ -69702,10 +69704,6 @@ declare module "babylonjs/Particles/particleSystemComponent" {
             getHierarchyEmittedParticleSystems(): IParticleSystem[];
         }
     }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild: number;
 }
 declare module "babylonjs/Particles/pointsCloudSystem" {
     import { Color4 } from "babylonjs/Maths/math";
@@ -70141,6 +70139,7 @@ declare module "babylonjs/Particles/index" {
     export * from "babylonjs/Particles/particle";
     export * from "babylonjs/Particles/particleHelper";
     export * from "babylonjs/Particles/particleSystem";
+    import "babylonjs/Particles/particleSystemComponent";
     export * from "babylonjs/Particles/particleSystemComponent";
     export * from "babylonjs/Particles/particleSystemSet";
     export * from "babylonjs/Particles/solidParticle";
@@ -93747,7 +93746,7 @@ declare module BABYLON {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Checks if the material is ready to render the requested mesh
          * @param mesh Define the mesh to render
@@ -101221,7 +101220,7 @@ declare module BABYLON {
          * @param useInstances specifies that instances should be used
          * @returns a boolean indicating that the submesh is ready or not
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Returns the material effect
          * @returns the effect associated with the material
@@ -101506,7 +101505,7 @@ declare module BABYLON {
          * @param useInstances Define whether or not the material is used with instances
          * @returns true if ready, otherwise false
          */
-        isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         /**
          * Clones the current material and its related sub materials
          * @param name Define the name of the newly cloned material
@@ -101537,9 +101536,19 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
-     * Base class for submeshes
+     * Defines a subdivision inside a mesh
      */
-    export class BaseSubMesh {
+    export class SubMesh implements ICullable {
+        /** the material index to use */
+        materialIndex: number;
+        /** vertex index start */
+        verticesStart: number;
+        /** vertices count */
+        verticesCount: number;
+        /** index start */
+        indexStart: number;
+        /** indices count */
+        indexCount: number;
         /** @hidden */
         _materialDefines: Nullable<MaterialDefines>;
         /** @hidden */
@@ -101564,21 +101573,6 @@ declare module BABYLON {
          * @param defines defines the set of defines used to compile this effect
          */
         setEffect(effect: Nullable<Effect>, defines?: Nullable<MaterialDefines>): void;
-    }
-    /**
-     * Defines a subdivision inside a mesh
-     */
-    export class SubMesh extends BaseSubMesh implements ICullable {
-        /** the material index to use */
-        materialIndex: number;
-        /** vertex index start */
-        verticesStart: number;
-        /** vertices count */
-        verticesCount: number;
-        /** index start */
-        indexStart: number;
-        /** indices count */
-        indexCount: number;
         /** @hidden */
         _linesIndexCount: number;
         private _mesh;
@@ -101662,6 +101656,16 @@ declare module BABYLON {
          */
         getRenderingMesh(): Mesh;
         /**
+         * Returns the replacement mesh of the submesh
+         * @returns the replacement mesh (could be different from parent mesh)
+         */
+        getReplacementMesh(): Nullable<AbstractMesh>;
+        /**
+         * Returns the effective mesh of the submesh
+         * @returns the effective mesh (could be different from parent mesh)
+         */
+        getEffectiveMesh(): AbstractMesh;
+        /**
          * Returns the submesh material
          * @returns null or the current material
          */
@@ -142163,10 +142167,6 @@ declare module BABYLON {
                 };
             };
         }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild2: number;
 }
 declare module BABYLON {
     /**
@@ -143388,10 +143388,6 @@ declare module BABYLON {
              */
             getHierarchyEmittedParticleSystems(): IParticleSystem[];
         }
-    /**
-     * @hidden
-     */
-    export var _IDoNeedToBeInTheBuild: number;
 }
 declare module BABYLON {
     /** Defines the 4 color options */

ファイルの差分が大きいため隠しています
+ 15 - 15
dist/preview release/viewer/babylon.viewer.js


ファイルの差分が大きいため隠しています
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -154,6 +154,10 @@
 - Added support for code templates in the playground ([sailro](http://www.github.com/sailro))
 - If createEngine fails, a default engine will be created ([#8084](https://github.com/BabylonJS/Babylon.js/issues/8084)) ([RaananW](https://github.com/RaananW))
 
+### GUI
+
+- Added support for custom word splitting function for `TextBlock` ([Popov72](https://github.com/Popov72))
+
 ## Bugs
 
 - Fix infinite loop in `GlowLayer.unReferenceMeshFromUsingItsOwnMaterial` ([Popov72](https://github.com/Popov72))
@@ -204,6 +208,9 @@
 - Fixed `Sound` not accepting a `TransformNode` as a source for spatial sound ([Poolminer](https://github.com/Poolminer))
 - Fixed an issue with transformation set after physics body was created using cannon.js ([#7928](https://github.com/BabylonJS/Babylon.js/issues/7928)) ([RaananW](https://github.com/RaananW))
 - Fix bug when using `ShadowOnlyMaterial` with Cascaded Shadow Map and `autoCalcDepthBounds` is `true` ([Popov72](https://github.com/Popov72))
+- Fix OBJ serializer default scene scene handedness causing [OBJ Mirror export](https://forum.babylonjs.com/t/obj-export-mirrored/10835/10)
+- Fix bug when using shadows + instances + transparent meshes + `transparencyShadow = false` ([Popov72](https://github.com/Popov72))
+- Incorrect initialization when reattaching XR pointer selection  ([#8227](https://github.com/BabylonJS/Babylon.js/issues/8227)) ([RaananW](https://github.com/RaananW))
 
 ## Breaking changes
 

+ 6 - 1
gui/src/2D/controls/textBlock.ts

@@ -50,6 +50,11 @@ export class TextBlock extends Control {
     public onLinesReadyObservable = new Observable<TextBlock>();
 
     /**
+     * Function used to split a string into words. By default, a string is split at each space character found
+     */
+    public wordSplittingFunction: Nullable<(line: string) => string[]>;
+
+    /**
      * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
      */
     public get lines(): any[] {
@@ -368,7 +373,7 @@ export class TextBlock extends Control {
     protected _parseLineWordWrap(line: string = '', width: number,
         context: CanvasRenderingContext2D): object[] {
         var lines = [];
-        var words = line.split(' ');
+        var words = this.wordSplittingFunction ? this.wordSplittingFunction(line) : line.split(' ');
         var lineWidth = 0;
 
         for (var n = 0; n < words.length; n++) {

+ 1 - 1
gui/src/3D/controls/control3D.ts

@@ -414,7 +414,7 @@ export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
             return true;
         }
 
-        if (type === PointerEventTypes.POINTERUP) {
+        if (type === PointerEventTypes.POINTERUP || type === PointerEventTypes.POINTERDOUBLETAP) {
             if (this._host._lastControlDown[pointerId]) {
                 this._host._lastControlDown[pointerId]._onPointerUp(this, pickedPoint, pointerId, buttonIndex, true);
             }

+ 3 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/animations/anchorSvgPoint.tsx

@@ -8,6 +8,7 @@ interface IAnchorSvgPointProps {
    active: boolean;
    type: string;
    index: string;
+   selected: boolean;
 }
 
 
@@ -20,9 +21,9 @@ export class AnchorSvgPoint extends React.Component<IAnchorSvgPointProps>{
         return (
         <>
             <svg x={this.props.control.x} y={this.props.control.y} style={{overflow:'visible'}}>
-                <circle type={this.props.type} data-id={this.props.index} className="draggable control-point" cx="0" cy="0"  r="2" stroke="none" strokeWidth="0" fill={this.props.active ? "blue" : "black"}   />
+                <circle type={this.props.type} data-id={this.props.index} className={`draggable control-point ${this.props.active ? 'active' : ''}`} cx="0" cy="0"  r="2" stroke="none" strokeWidth="0" fill={this.props.active ? "blue" : "black"}   />
             </svg>
-            <line x1={this.props.anchor.x} y1={this.props.anchor.y} x2={this.props.control.x} y2={this.props.control.y} stroke="green" strokeWidth="0.75" />
+            <line className={`control-point ${this.props.active ? 'active' : ''}`} x1={this.props.anchor.x} y1={this.props.anchor.y} x2={this.props.control.x} y2={this.props.control.y} stroke="green" strokeWidth="0.75" />
         </>
         )
     }

ファイルの差分が大きいため隠しています
+ 210 - 23
inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent.tsx


+ 21 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/animations/curveEditor.scss

@@ -142,7 +142,17 @@
             ul {
                 list-style:none;
                 padding-left: 0px;
+                li.property {
+                    &:before {
+                        content: '';
+                        background: none;
+                    }
+                }
                 li {
+                    p {
+                        font-weight: bolder;
+                        font-variant: all-small-caps;
+                    }
                     cursor: pointer;
                     &:before {
                         content: '';
@@ -170,7 +180,9 @@
                 background-color: rgba(0, 0, 0, 0.3);
                 padding: 10px;
                 margin-top: 19px;
-                height: 15em;
+                height: 11em;
+                overflow: scroll;
+                overflow-x: hidden;
             }
 
             .label-input{
@@ -218,6 +230,14 @@
                 text {
                     fill: #cecece;
                 }
+
+                .control-point {
+                    display: none;
+                }
+
+                .control-point.active {
+                    display: inline;
+                }
             }
 
             .playhead-wrapper {

+ 9 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/animations/graphActionsBar.tsx

@@ -4,9 +4,12 @@ import { ButtonLineComponent } from '../../../lines/buttonLineComponent';
 
 interface IGraphActionsBarProps {
    addKeyframe: () => void;
+   removeKeyframe: () => void;
    handleValueChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
+   handleFrameChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
    flatTangent: () => void;
    currentValue: number;
+   currentFrame: number;
 }
 
 export class GraphActionsBar extends React.Component<IGraphActionsBarProps>{ 
@@ -18,10 +21,15 @@ export class GraphActionsBar extends React.Component<IGraphActionsBarProps>{
        return (
            <div className="actions-wrapper">
                <div className="action-input">
+               <label>Frame</label>
+               <input type="number" value={this.props.currentFrame} onChange={this.props.handleFrameChange} step="1"/>
+               </div>
+               <div className="action-input">
                <label>Value</label>
-               <input type="number" value={this.props.currentValue} onChange={this.props.handleValueChange}/>
+               <input type="number" value={this.props.currentValue.toFixed(3)} onChange={this.props.handleValueChange} step="0.001"/>
                </div>
               <ButtonLineComponent label={"Add Keyframe"} onClick={this.props.addKeyframe} />
+              <ButtonLineComponent label={"Remove Keyframe"} onClick={this.props.removeKeyframe} />
               <ButtonLineComponent label={"Flat Tangent"} onClick={this.props.flatTangent} />
            </div>
         )

+ 2 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/animations/keyframeSvgPoint.tsx

@@ -28,8 +28,8 @@ export class KeyframeSvgPoint extends React.Component<IKeyframeSvgPointProps>{
                 <svg className="draggable" x={this.props.keyframePoint.x} y={this.props.keyframePoint.y} style={{overflow:'visible'}}>
                     <circle data-id={this.props.id} className="draggable" cx="0" cy="0"  r="2" stroke="none" strokeWidth="0" fill="red" />
                 </svg>
-               { this.props.leftControlPoint && <AnchorSvgPoint type="left" index={this.props.id} control={this.props.leftControlPoint} anchor={this.props.keyframePoint} active={false}/>} 
-               { this.props.rightControlPoint &&  <AnchorSvgPoint type="right" index={this.props.id} control={this.props.rightControlPoint} anchor={this.props.keyframePoint} active={false}/>}
+               { this.props.leftControlPoint && <AnchorSvgPoint type="left" index={this.props.id} control={this.props.leftControlPoint} anchor={this.props.keyframePoint} active={false} selected={false}/>} 
+               { this.props.rightControlPoint &&  <AnchorSvgPoint type="right" index={this.props.id} control={this.props.rightControlPoint} anchor={this.props.keyframePoint} active={false} selected={false}/>}
             </>
         )
     }

+ 1 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/commonPropertyGridComponent.tsx

@@ -74,7 +74,7 @@ export class CommonPropertyGridComponent extends React.Component<ICommonProperty
 
         return (
             <div>
-                <LineContainerComponent globalState={this.props.globalState} title="XMP METADA">
+                <LineContainerComponent globalState={this.props.globalState} title="XMP METADATA">
                     {
                         this.renderLevel(this.props.host.metadata.xmp)                        
                     }

+ 7 - 1
serializers/src/OBJ/objSerializer.ts

@@ -67,7 +67,13 @@ export class OBJExport {
             }
 
             for (var i = 0; i < trunkVerts.length; i += 3) {
-                output.push("v " + trunkVerts[i] + " " + trunkVerts[i + 1] + " " + trunkVerts[i + 2]);
+                // Babylon.js default is left handed, while OBJ default is right handed
+                // Need to invert Z vertices unless Babylon is set to use a right handed system
+                if (mesh[0].getScene().useRightHandedSystem) {
+                    output.push("v " + trunkVerts[i] + " " + trunkVerts[i + 1] + " " + trunkVerts[i + 2]);
+                } else {
+                    output.push("v " + trunkVerts[i] + " " + trunkVerts[i + 1] + " " + -trunkVerts[i + 2]);
+                }
                 curV++;
             }
 

+ 1 - 1
src/DeviceInput/InputDevices/deviceSourceManager.ts

@@ -81,7 +81,7 @@ export class DeviceSourceManager implements IDisposable {
         const numberOfDeviceTypes = Object.keys(DeviceType).length / 2;
         this._devices = new Array<Array<DeviceSource<DeviceType>>>(numberOfDeviceTypes);
         this._firstDevice = new Array<number>(numberOfDeviceTypes);
-        this._deviceInputSystem = new DeviceInputSystem(engine);
+        this._deviceInputSystem = DeviceInputSystem.Create(engine);
 
         this._deviceInputSystem.onDeviceConnected = (deviceType, deviceSlot) => {
             this.onBeforeDeviceConnectedObservable.notifyObservers({ deviceType, deviceSlot });

+ 18 - 5
src/DeviceInput/deviceInputSystem.ts

@@ -3,6 +3,9 @@ import { IDisposable } from '../scene';
 import { Nullable } from '../types';
 import { DeviceType } from './InputDevices/deviceEnums';
 
+/** @hidden */
+declare const _native: any;
+
 /**
  * This class will take all inputs from Keyboard, Pointer, and
  * any Gamepads and provide a polling system that all devices
@@ -45,11 +48,7 @@ export class DeviceInputSystem implements IDisposable {
     private static _MAX_KEYCODES: number = 255;
     private static _MAX_POINTER_INPUTS: number = 7;
 
-    /**
-     * Default Constructor
-     * @param engine - engine to pull input element from
-     */
-    constructor(engine: Engine) {
+    private constructor(engine: Engine) {
         const inputElement = engine.getInputElement();
         if (inputElement) {
             this._elementToAttachTo = inputElement;
@@ -59,6 +58,20 @@ export class DeviceInputSystem implements IDisposable {
         }
     }
 
+    /**
+     * Creates a new DeviceInputSystem instance
+     * @param engine Engine to pull input element from
+     * @returns The new instance
+     */
+    public static Create(engine: Engine): DeviceInputSystem {
+        // If running in Babylon Native, then defer to the native input system, which has the same public contract
+        if (typeof _native.DeviceInputSystem !== 'undefined') {
+            return new _native.DeviceInputSystem(engine);
+        }
+
+        return new DeviceInputSystem(engine);
+    }
+
     // Public functions
     /**
      * Checks for current device input value, given an id and input index

+ 2 - 2
src/Layers/effectLayer.ts

@@ -657,9 +657,9 @@ export abstract class EffectLayer {
 
         var material = subMesh.getMaterial();
         var ownerMesh = subMesh.getMesh();
-        var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh : null;
+        var replacementMesh = subMesh.getReplacementMesh();
         var renderingMesh = subMesh.getRenderingMesh();
-        var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
+        var effectiveMesh = subMesh.getEffectiveMesh();
         var scene = this._scene;
         var engine = scene.getEngine();
 

+ 6 - 4
src/Lights/Shadows/shadowGenerator.ts

@@ -1030,6 +1030,10 @@ export class ShadowGenerator implements IShadowGenerator {
             for (index = 0; index < transparentSubMeshes.length; index++) {
                 this._renderSubMeshForShadowMap(transparentSubMeshes.data[index], true);
             }
+        } else {
+            for (index = 0; index < transparentSubMeshes.length; index++) {
+                transparentSubMeshes.data[index].getEffectiveMesh()._internalAbstractMeshDataInfo._isActiveIntermediate = false;
+            }
         }
     }
 
@@ -1054,10 +1058,8 @@ export class ShadowGenerator implements IShadowGenerator {
     }
 
     protected _renderSubMeshForShadowMap(subMesh: SubMesh, isTransparent: boolean = false): void {
-        var ownerMesh = subMesh.getMesh();
-        var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh : null;
         var renderingMesh = subMesh.getRenderingMesh();
-        var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
+        var effectiveMesh = subMesh.getEffectiveMesh();
         var scene = this._scene;
         var engine = scene.getEngine();
         let material = subMesh.getMaterial();
@@ -1072,7 +1074,7 @@ export class ShadowGenerator implements IShadowGenerator {
         engine.setState(material.backFaceCulling);
 
         // Managing instances
-        var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);
+        var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());
         if (batch.mustReturn) {
             return;
         }

+ 35 - 15
src/Materials/material.ts

@@ -7,7 +7,7 @@ import { Nullable } from "../types";
 import { Scene } from "../scene";
 import { Matrix } from "../Maths/math.vector";
 import { EngineStore } from "../Engines/engineStore";
-import { BaseSubMesh, SubMesh } from "../Meshes/subMesh";
+import { SubMesh } from "../Meshes/subMesh";
 import { Geometry } from "../Meshes/geometry";
 import { AbstractMesh } from "../Meshes/abstractMesh";
 import { UniformBuffer } from "./uniformBuffer";
@@ -709,7 +709,7 @@ export class Material implements IAnimatable {
      * @param useInstances specifies that instances should be used
      * @returns a boolean indicating that the submesh is ready or not
      */
-    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean {
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
         return false;
     }
 
@@ -1044,7 +1044,6 @@ export class Material implements IAnimatable {
             ...options
         };
 
-        var subMesh = new BaseSubMesh();
         var scene = this.getScene();
 
         var checkReady = () => {
@@ -1052,10 +1051,6 @@ export class Material implements IAnimatable {
                 return;
             }
 
-            if (subMesh._materialDefines) {
-                subMesh._materialDefines._renderId = -1;
-            }
-
             var clipPlaneState = scene.clipPlane;
 
             if (localOptions.clipPlane) {
@@ -1063,18 +1058,43 @@ export class Material implements IAnimatable {
             }
 
             if (this._storeEffectOnSubMeshes) {
-                if (this.isReadyForSubMesh(mesh, subMesh, localOptions.useInstances)) {
-                    if (onCompiled) {
-                        onCompiled(this);
+                var allDone = true, lastError = null;
+                if (mesh.subMeshes) {
+                    for (var subMesh of mesh.subMeshes) {
+                        let effectiveMaterial = subMesh.getMaterial();
+                        if (effectiveMaterial) {
+                            if (effectiveMaterial._storeEffectOnSubMeshes) {
+                                if (!effectiveMaterial.isReadyForSubMesh(mesh, subMesh, localOptions.useInstances)) {
+                                    if (subMesh.effect && subMesh.effect.getCompilationError() && subMesh.effect.allFallbacksProcessed()) {
+                                        lastError = subMesh.effect.getCompilationError();
+                                    } else {
+                                        allDone = false;
+                                        setTimeout(checkReady, 16);
+                                        break;
+                                    }
+                                }
+                            } else {
+                                if (!effectiveMaterial.isReady(mesh, localOptions.useInstances)) {
+                                    if (effectiveMaterial.getEffect() && effectiveMaterial.getEffect()!.getCompilationError() && effectiveMaterial.getEffect()!.allFallbacksProcessed()) {
+                                        lastError = effectiveMaterial.getEffect()!.getCompilationError();
+                                    } else {
+                                        allDone = false;
+                                        setTimeout(checkReady, 16);
+                                        break;
+                                    }
+                                }
+                            }
+                        }
                     }
                 }
-                else {
-                    if (subMesh.effect && subMesh.effect.getCompilationError() && subMesh.effect.allFallbacksProcessed()) {
+                if (allDone) {
+                    if (lastError) {
                         if (onError) {
-                            onError(subMesh.effect.getCompilationError());
+                            onError(lastError);
                         }
-                    } else {
-                        setTimeout(checkReady, 16);
+                    }
+                    if (onCompiled) {
+                        onCompiled(this);
                     }
                 }
             } else {

+ 2 - 2
src/Materials/multiMaterial.ts

@@ -1,7 +1,7 @@
 import { Nullable } from "../types";
 import { Scene } from "../scene";
 import { AbstractMesh } from "../Meshes/abstractMesh";
-import { BaseSubMesh } from "../Meshes/subMesh";
+import { SubMesh } from "../Meshes/subMesh";
 import { BaseTexture } from "../Materials/Textures/baseTexture";
 import { Material } from "../Materials/material";
 import { Tags } from "../Misc/tags";
@@ -117,7 +117,7 @@ export class MultiMaterial extends Material {
      * @param useInstances Define whether or not the material is used with instances
      * @returns true if ready, otherwise false
      */
-    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean {
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
         for (var index = 0; index < this.subMaterials.length; index++) {
             var subMaterial = this.subMaterials[index];
             if (subMaterial) {

+ 2 - 2
src/Materials/shaderMaterial.ts

@@ -4,7 +4,7 @@ import { Scene } from "../scene";
 import { Matrix, Vector3, Vector2, Vector4 } from "../Maths/math.vector";
 import { AbstractMesh } from "../Meshes/abstractMesh";
 import { Mesh } from "../Meshes/mesh";
-import { SubMesh, BaseSubMesh } from "../Meshes/subMesh";
+import { SubMesh } from "../Meshes/subMesh";
 import { VertexBuffer } from "../Meshes/buffer";
 import { BaseTexture } from "../Materials/Textures/baseTexture";
 import { Texture } from "../Materials/Textures/texture";
@@ -463,7 +463,7 @@ export class ShaderMaterial extends Material {
      * @param useInstances specifies that instances should be used
      * @returns a boolean indicating that the submesh is ready or not
      */
-    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: BaseSubMesh, useInstances?: boolean): boolean {
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
         return this.isReady(mesh, useInstances);
     }
 

+ 1 - 0
src/Meshes/index.ts

@@ -19,4 +19,5 @@ export * from "./transformNode";
 export * from "./Builders/index";
 export * from "./dataBuffer";
 export * from "./WebGL/webGLDataBuffer";
+import "./thinInstanceMesh";
 export * from "./thinInstanceMesh";

+ 20 - 8
src/Meshes/subMesh.ts

@@ -20,9 +20,9 @@ declare type Ray = import("../Culling/ray").Ray;
 declare type TrianglePickingPredicate = import("../Culling/ray").TrianglePickingPredicate;
 
 /**
- * Base class for submeshes
+ * Defines a subdivision inside a mesh
  */
-export class BaseSubMesh {
+export class SubMesh implements ICullable {
     /** @hidden */
     public _materialDefines: Nullable<MaterialDefines> = null;
     /** @hidden */
@@ -66,12 +66,7 @@ export class BaseSubMesh {
         this._materialDefines = defines;
         this._materialEffect = effect;
     }
-}
 
-/**
- * Defines a subdivision inside a mesh
- */
-export class SubMesh extends BaseSubMesh implements ICullable {
     /** @hidden */
     public _linesIndexCount: number = 0;
     private _mesh: AbstractMesh;
@@ -134,7 +129,6 @@ export class SubMesh extends BaseSubMesh implements ICullable {
         public indexStart: number,
         /** indices count */
         public indexCount: number, mesh: AbstractMesh, renderingMesh?: Mesh, createBoundingBox: boolean = true) {
-        super();
         this._mesh = mesh;
         this._renderingMesh = renderingMesh || <Mesh>mesh;
         mesh.subMeshes.push(this);
@@ -196,6 +190,24 @@ export class SubMesh extends BaseSubMesh implements ICullable {
     }
 
     /**
+     * Returns the replacement mesh of the submesh
+     * @returns the replacement mesh (could be different from parent mesh)
+     */
+    public getReplacementMesh(): Nullable<AbstractMesh> {
+        return this._mesh._internalAbstractMeshDataInfo._actAsRegularMesh ? this._mesh : null;
+    }
+
+    /**
+     * Returns the effective mesh of the submesh
+     * @returns the effective mesh (could be different from parent mesh)
+     */
+    public getEffectiveMesh(): AbstractMesh {
+        const replacementMesh = this._mesh._internalAbstractMeshDataInfo._actAsRegularMesh ? this._mesh : null;
+
+        return replacementMesh ? replacementMesh : this._renderingMesh;
+    }
+
+    /**
      * Returns the submesh material
      * @returns null or the current material
      */

+ 0 - 5
src/Meshes/thinInstanceMesh.ts

@@ -343,8 +343,3 @@ Mesh.prototype._disposeThinInstanceSpecificData = function() {
         this._thinInstanceDataStorage.matrixBuffer = null;
     }
 };
-
-/**
- * @hidden
- */
-export var _IDoNeedToBeInTheBuild2 = 42;

+ 12 - 25
src/Particles/EmitterTypes/coneParticleEmitter.ts

@@ -1,5 +1,5 @@
 import { DeepCopier } from "../../Misc/deepCopier";
-import { Vector3, Matrix } from "../../Maths/math.vector";
+import { Vector3, Matrix, TmpVectors } from "../../Maths/math.vector";
 import { Scalar } from "../../Maths/math.scalar";
 import { Effect } from "../../Materials/effect";
 import { Particle } from "../../Particles/particle";
@@ -83,33 +83,20 @@ export class ConeParticleEmitter implements IParticleEmitterType {
      * @param isLocal defines if the direction should be set in local space
      */
     public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
-        if (Math.abs(Math.cos(this._angle)) === 1.0) {
-            if (isLocal) {
-                directionToUpdate.x = 0;
-                directionToUpdate.y = 1.0;
-                directionToUpdate.z = 0;
-                return;
-            }
-            Vector3.TransformNormalFromFloatsToRef(0, 1.0, 0, worldMatrix, directionToUpdate);
+        if (isLocal) {
+            TmpVectors.Vector3[0].copyFrom(particle._localPosition!).normalize();
         }
         else {
-            // measure the direction Vector from the emitter to the particle.
-            var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
-            var randX = Scalar.RandomRange(0, this.directionRandomizer);
-            var randY = Scalar.RandomRange(0, this.directionRandomizer);
-            var randZ = Scalar.RandomRange(0, this.directionRandomizer);
-            direction.x += randX;
-            direction.y += randY;
-            direction.z += randZ;
-            direction.normalize();
-
-            if (isLocal) {
-                directionToUpdate.copyFrom(direction);
-                return;
-            }
-
-            Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
+            particle.position.subtractToRef(worldMatrix.getTranslation(), TmpVectors.Vector3[0]).normalize();
         }
+
+        var randX = Scalar.RandomRange(0, this.directionRandomizer);
+        var randY = Scalar.RandomRange(0, this.directionRandomizer);
+        var randZ = Scalar.RandomRange(0, this.directionRandomizer);
+        directionToUpdate.x = TmpVectors.Vector3[0].x + randX;
+        directionToUpdate.y = TmpVectors.Vector3[0].y + randY;
+        directionToUpdate.z = TmpVectors.Vector3[0].z + randZ;
+        directionToUpdate.normalize();
     }
 
     /**

+ 2 - 0
src/Particles/index.ts

@@ -5,6 +5,8 @@ export * from "./IParticleSystem";
 export * from "./particle";
 export * from "./particleHelper";
 export * from "./particleSystem";
+
+import "./particleSystemComponent";
 export * from "./particleSystemComponent";
 export * from "./particleSystemSet";
 export * from "./solidParticle";

+ 0 - 5
src/Particles/particleSystemComponent.ts

@@ -136,8 +136,3 @@ Mesh.prototype.getHierarchyEmittedParticleSystems = function(): IParticleSystem[
 
     return results;
 };
-
-/**
- * @hidden
- */
-export var _IDoNeedToBeInTheBuild = 42;

+ 2 - 4
src/PostProcesses/volumetricLightScatteringPostProcess.ts

@@ -294,10 +294,8 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {
 
         // Custom render function for submeshes
         var renderSubMesh = (subMesh: SubMesh): void => {
-            var ownerMesh = subMesh.getMesh();
-            var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh : null;
             var renderingMesh = subMesh.getRenderingMesh();
-            var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
+            var effectiveMesh = subMesh.getEffectiveMesh();
             if (this._meshExcluded(renderingMesh)) {
                 return;
             }
@@ -317,7 +315,7 @@ export class VolumetricLightScatteringPostProcess extends PostProcess {
             engine.setState(material.backFaceCulling);
 
             // Managing instances
-            var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);
+            var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());
 
             if (batch.mustReturn) {
                 return;

+ 2 - 4
src/Rendering/depthRenderer.ts

@@ -94,10 +94,8 @@ export class DepthRenderer {
 
         // Custom render function
         var renderSubMesh = (subMesh: SubMesh): void => {
-            var ownerMesh = subMesh.getMesh();
-            var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh : null;
             var renderingMesh = subMesh.getRenderingMesh();
-            var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
+            var effectiveMesh = subMesh.getEffectiveMesh();
             var scene = this._scene;
             var engine = scene.getEngine();
             let material = subMesh.getMaterial();
@@ -112,7 +110,7 @@ export class DepthRenderer {
             engine.setState(material.backFaceCulling, 0, false, scene.useRightHandedSystem);
 
             // Managing instances
-            var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);
+            var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());
 
             if (batch.mustReturn) {
                 return;

+ 2 - 4
src/Rendering/geometryBufferRenderer.ts

@@ -393,10 +393,8 @@ export class GeometryBufferRenderer {
 
         // Custom render function
         var renderSubMesh = (subMesh: SubMesh): void => {
-            var ownerMesh = subMesh.getMesh();
-            var replacementMesh = ownerMesh._internalAbstractMeshDataInfo._actAsRegularMesh ? ownerMesh : null;
             var renderingMesh = subMesh.getRenderingMesh();
-            var effectiveMesh = replacementMesh ? replacementMesh : renderingMesh;
+            var effectiveMesh = subMesh.getEffectiveMesh();
             var scene = this._scene;
             var engine = scene.getEngine();
             let material = <any> subMesh.getMaterial();
@@ -424,7 +422,7 @@ export class GeometryBufferRenderer {
             engine.setState(material.backFaceCulling, 0, false, scene.useRightHandedSystem);
 
             // Managing instances
-            var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!replacementMesh);
+            var batch = renderingMesh._getInstancesRenderList(subMesh._id, !!subMesh.getReplacementMesh());
 
             if (batch.mustReturn) {
                 return;

+ 8 - 2
src/XR/features/WebXRControllerPointerSelection.ts

@@ -17,6 +17,7 @@ import { Ray } from '../../Culling/ray';
 import { PickingInfo } from '../../Collisions/pickingInfo';
 import { WebXRAbstractFeature } from './WebXRAbstractFeature';
 import { UtilityLayerRenderer } from '../../Rendering/utilityLayerRenderer';
+import { WebXRAbstractMotionController } from '../motionController/webXRAbstractMotionController';
 
 /**
  * Options interface for the pointer selection module
@@ -398,7 +399,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
             }
         });
         if (xrController.inputSource.gamepad) {
-            xrController.onMotionControllerInitObservable.add((motionController) => {
+            const init = (motionController: WebXRAbstractMotionController) => {
                 if (this._options.overrideButtonId) {
                     controllerData.selectionComponent = motionController.getComponent(this._options.overrideButtonId);
                 }
@@ -422,7 +423,12 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
                         }
                     }
                 });
-            });
+            };
+            if (xrController.motionController) {
+                init(xrController.motionController);
+            } else {
+                xrController.onMotionControllerInitObservable.add(init);
+            }
         } else {
             // use the select and squeeze events
             const selectStartListener = (event: XRInputSourceEvent) => {