David Catuhe 5 lat temu
rodzic
commit
8b482339d1
30 zmienionych plików z 726 dodań i 201 usunięć
  1. 52 18
      dist/preview release/babylon.d.ts
  2. 2 2
      dist/preview release/babylon.js
  3. 159 20
      dist/preview release/babylon.max.js
  4. 1 1
      dist/preview release/babylon.max.js.map
  5. 104 36
      dist/preview release/babylon.module.d.ts
  6. 52 18
      dist/preview release/documentation.d.ts
  7. 2 0
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  8. 2 2
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  9. 35 32
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  10. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  11. 4 0
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  12. 104 36
      dist/preview release/viewer/babylon.module.d.ts
  13. 11 11
      dist/preview release/viewer/babylon.viewer.js
  14. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  15. 1 0
      dist/preview release/what's new.md
  16. 2 1
      nodeEditor/src/components/preview/previewAreaComponent.tsx
  17. 6 0
      src/Engines/Extensions/engine.views.ts
  18. 4 2
      src/Particles/EmitterTypes/IParticleEmitterType.ts
  19. 18 2
      src/Particles/EmitterTypes/boxParticleEmitter.ts
  20. 22 2
      src/Particles/EmitterTypes/coneParticleEmitter.ts
  21. 14 2
      src/Particles/EmitterTypes/customParticleEmitter.ts
  22. 14 2
      src/Particles/EmitterTypes/cylinderParticleEmitter.ts
  23. 15 2
      src/Particles/EmitterTypes/hemisphericParticleEmitter.ts
  24. 14 3
      src/Particles/EmitterTypes/meshParticleEmitter.ts
  25. 13 2
      src/Particles/EmitterTypes/pointParticleEmitter.ts
  26. 15 2
      src/Particles/EmitterTypes/sphereParticleEmitter.ts
  27. 5 0
      src/Particles/IParticleSystem.ts
  28. 12 0
      src/Particles/gpuParticleSystem.ts
  29. 3 0
      src/Particles/particle.ts
  30. 38 3
      src/Particles/particleSystem.ts

+ 52 - 18
dist/preview release/babylon.d.ts

@@ -11601,6 +11601,10 @@ declare module BABYLON {
         * The current active Sub-systems, this property is used by the root particle system only.
         */
         activeSubSystems: Array<ParticleSystem>;
+        /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
         private _rootParticleSystem;
         /**
          * Gets the current list of active particles
@@ -12019,6 +12023,8 @@ declare module BABYLON {
         _randomNoiseCoordinates1: Vector3;
         /** @hidden */
         _randomNoiseCoordinates2: Vector3;
+        /** @hidden */
+        _localPosition?: Vector3;
         /**
          * Creates a new instance Particle
          * @param particleSystem the particle system the particle belongs to
@@ -12057,15 +12063,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12130,15 +12138,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12220,15 +12230,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12312,15 +12324,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12463,15 +12477,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12527,15 +12543,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12610,15 +12628,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12741,15 +12761,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12818,15 +12840,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -13068,6 +13092,10 @@ declare module BABYLON {
          */
         disposeOnStop: boolean;
         /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
+        /**
          * Gets the maximum number of particles active at the same time.
          * @returns The max number of active particles.
          */
@@ -62409,6 +62437,12 @@ declare module BABYLON {
         set activeParticleCount(value: number);
         private _preWarmDone;
         /**
+         * Specifies if the particles are updated in emitter local space or world space.
+         * This is always false for GPU particles
+         */
+        get isLocal(): boolean;
+        set isLocal(value: boolean);
+        /**
          * Is this system ready to be used/rendered
          * @return true if the system is ready
          */

Plik diff jest za duży
+ 2 - 2
dist/preview release/babylon.js


+ 159 - 20
dist/preview release/babylon.max.js

@@ -30729,6 +30729,11 @@ _engine__WEBPACK_IMPORTED_MODULE_0__["Engine"].prototype.registerView = function
             return view;
         }
     }
+    var masterCanvas = this.getRenderingCanvas();
+    if (masterCanvas) {
+        canvas.width = masterCanvas.width;
+        canvas.height = masterCanvas.height;
+    }
     var newView = { target: canvas, camera: camera };
     this.views.push(newView);
     if (camera) {
@@ -137643,11 +137648,18 @@ var BoxParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    BoxParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
+    BoxParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle, isLocal) {
         var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.x, this.direction2.x);
         var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.y, this.direction2.y);
         var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.z, this.direction2.z);
+        if (isLocal) {
+            directionToUpdate.x = randX;
+            directionToUpdate.y = randY;
+            directionToUpdate.z = randZ;
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
     };
     /**
@@ -137655,11 +137667,18 @@ var BoxParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    BoxParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
+    BoxParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle, isLocal) {
         var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.minEmitBox.x, this.maxEmitBox.x);
         var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.minEmitBox.y, this.maxEmitBox.y);
         var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.minEmitBox.z, this.maxEmitBox.z);
+        if (isLocal) {
+            positionToUpdate.x = randX;
+            positionToUpdate.y = randY;
+            positionToUpdate.z = randZ;
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
     };
     /**
@@ -137816,9 +137835,16 @@ var ConeParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    ConeParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
+    ConeParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle, isLocal) {
         if (Math.abs(Math.cos(this._angle)) === 1.0) {
+            if (isLocal) {
+                directionToUpdate.x = 0;
+                directionToUpdate.y = 1.0;
+                directionToUpdate.z = 0;
+                return;
+            }
             _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(0, 1.0, 0, worldMatrix, directionToUpdate);
         }
         else {
@@ -137831,6 +137857,10 @@ var ConeParticleEmitter = /** @class */ (function () {
             direction.y += randY;
             direction.z += randZ;
             direction.normalize();
+            if (isLocal) {
+                directionToUpdate.copyFrom(direction);
+                return;
+            }
             _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
         }
     };
@@ -137839,8 +137869,9 @@ var ConeParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    ConeParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
+    ConeParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle, isLocal) {
         var s = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, Math.PI * 2);
         var h;
         if (!this.emitFromSpawnPointOnly) {
@@ -137856,6 +137887,12 @@ var ConeParticleEmitter = /** @class */ (function () {
         var randX = radius * Math.sin(s);
         var randZ = radius * Math.cos(s);
         var randY = h * this._height;
+        if (isLocal) {
+            positionToUpdate.x = randX;
+            positionToUpdate.y = randY;
+            positionToUpdate.z = randZ;
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
     };
     /**
@@ -137967,8 +138004,9 @@ var CustomParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    CustomParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
+    CustomParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle, isLocal) {
         var tmpVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[0];
         if (this.particleDestinationGenerator) {
             this.particleDestinationGenerator(-1, particle, tmpVector);
@@ -137980,6 +138018,10 @@ var CustomParticleEmitter = /** @class */ (function () {
         else {
             tmpVector.set(0, 0, 0);
         }
+        if (isLocal) {
+            directionToUpdate.copyFrom(tmpVector);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalToRef(tmpVector, worldMatrix, directionToUpdate);
     };
     /**
@@ -137987,8 +138029,9 @@ var CustomParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    CustomParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
+    CustomParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle, isLocal) {
         var tmpVector = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["TmpVectors"].Vector3[0];
         if (this.particlePositionGenerator) {
             this.particlePositionGenerator(-1, particle, tmpVector);
@@ -137996,6 +138039,10 @@ var CustomParticleEmitter = /** @class */ (function () {
         else {
             tmpVector.set(0, 0, 0);
         }
+        if (isLocal) {
+            positionToUpdate.copyFrom(tmpVector);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesToRef(tmpVector, worldMatrix, positionToUpdate);
     };
     /**
@@ -138111,8 +138158,9 @@ var CylinderParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    CylinderParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
+    CylinderParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle, isLocal) {
         var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
         var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(-this.directionRandomizer / 2, this.directionRandomizer / 2);
         var angle = Math.atan2(direction.x, direction.z);
@@ -138121,6 +138169,10 @@ var CylinderParticleEmitter = /** @class */ (function () {
         direction.x = Math.sin(angle);
         direction.z = Math.cos(angle);
         direction.normalize();
+        if (isLocal) {
+            directionToUpdate.copyFrom(direction);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
     };
     /**
@@ -138128,8 +138180,9 @@ var CylinderParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    CylinderParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
+    CylinderParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle, isLocal) {
         var yPos = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(-this.height / 2, this.height / 2);
         var angle = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 2 * Math.PI);
         // Pick a properly distributed point within the circle https://programming.guide/random-point-within-circle.html
@@ -138137,6 +138190,10 @@ var CylinderParticleEmitter = /** @class */ (function () {
         var positionRadius = Math.sqrt(radiusDistribution) * this.radius;
         var xPos = positionRadius * Math.cos(angle);
         var zPos = positionRadius * Math.sin(angle);
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(xPos, yPos, zPos);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(xPos, yPos, zPos, worldMatrix, positionToUpdate);
     };
     /**
@@ -138355,8 +138412,9 @@ var HemisphericParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    HemisphericParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
+    HemisphericParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle, isLocal) {
         var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
         var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
         var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
@@ -138365,6 +138423,10 @@ var HemisphericParticleEmitter = /** @class */ (function () {
         direction.y += randY;
         direction.z += randZ;
         direction.normalize();
+        if (isLocal) {
+            directionToUpdate.copyFrom(direction);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
     };
     /**
@@ -138372,8 +138434,9 @@ var HemisphericParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    HemisphericParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
+    HemisphericParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle, isLocal) {
         var randRadius = this.radius - _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.radius * this.radiusRange);
         var v = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 1.0);
         var phi = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 2 * Math.PI);
@@ -138381,6 +138444,10 @@ var HemisphericParticleEmitter = /** @class */ (function () {
         var randX = randRadius * Math.cos(phi) * Math.sin(theta);
         var randY = randRadius * Math.cos(theta);
         var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(randX, Math.abs(randY), randZ);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randX, Math.abs(randY), randZ, worldMatrix, positionToUpdate);
     };
     /**
@@ -138550,8 +138617,9 @@ var MeshParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    MeshParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
+    MeshParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle, isLocal) {
         if (this.useMeshNormalsForDirection && this._normals) {
             _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalToRef(this._storedNormal, worldMatrix, directionToUpdate);
             return;
@@ -138559,6 +138627,10 @@ var MeshParticleEmitter = /** @class */ (function () {
         var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.x, this.direction2.x);
         var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.y, this.direction2.y);
         var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.z, this.direction2.z);
+        if (isLocal) {
+            directionToUpdate.copyFromFloats(randX, randY, randZ);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
     };
     /**
@@ -138566,8 +138638,9 @@ var MeshParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    MeshParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
+    MeshParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle, isLocal) {
         if (!this._indices || !this._positions) {
             return;
         }
@@ -138588,7 +138661,12 @@ var MeshParticleEmitter = /** @class */ (function () {
         randomVertex.x = bu * vertexA.x + bv * vertexB.x + bw * vertexC.x;
         randomVertex.y = bu * vertexA.y + bv * vertexB.y + bw * vertexC.y;
         randomVertex.z = bu * vertexA.z + bv * vertexB.z + bw * vertexC.z;
-        _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randomVertex.x, randomVertex.y, randomVertex.z, worldMatrix, positionToUpdate);
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(randomVertex.x, randomVertex.y, randomVertex.z);
+        }
+        else {
+            _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randomVertex.x, randomVertex.y, randomVertex.z, worldMatrix, positionToUpdate);
+        }
         if (this.useMeshNormalsForDirection && this._normals) {
             _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(this._normals, faceIndexA * 3, vertexA);
             _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].FromArrayToRef(this._normals, faceIndexB * 3, vertexB);
@@ -138702,11 +138780,16 @@ var PointParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    PointParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
+    PointParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle, isLocal) {
         var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.x, this.direction2.x);
         var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.y, this.direction2.y);
         var randZ = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(this.direction1.z, this.direction2.z);
+        if (isLocal) {
+            directionToUpdate.copyFromFloats(randX, randY, randZ);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
     };
     /**
@@ -138714,8 +138797,13 @@ var PointParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    PointParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
+    PointParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle, isLocal) {
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(0, 0, 0);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(0, 0, 0, worldMatrix, positionToUpdate);
     };
     /**
@@ -138830,8 +138918,9 @@ var SphereParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    SphereParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle) {
+    SphereParticleEmitter.prototype.startDirectionFunction = function (worldMatrix, directionToUpdate, particle, isLocal) {
         var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
         var randX = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
         var randY = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.directionRandomizer);
@@ -138840,6 +138929,10 @@ var SphereParticleEmitter = /** @class */ (function () {
         direction.y += randY;
         direction.z += randZ;
         direction.normalize();
+        if (isLocal) {
+            directionToUpdate.copyFrom(direction);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
     };
     /**
@@ -138847,8 +138940,9 @@ var SphereParticleEmitter = /** @class */ (function () {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    SphereParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle) {
+    SphereParticleEmitter.prototype.startPositionFunction = function (worldMatrix, positionToUpdate, particle, isLocal) {
         var randRadius = this.radius - _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, this.radius * this.radiusRange);
         var v = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 1.0);
         var phi = _Maths_math_scalar__WEBPACK_IMPORTED_MODULE_2__["Scalar"].RandomRange(0, 2 * Math.PI);
@@ -138856,6 +138950,10 @@ var SphereParticleEmitter = /** @class */ (function () {
         var randX = randRadius * Math.cos(phi) * Math.sin(theta);
         var randY = randRadius * Math.cos(theta);
         var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(randX, randY, randZ);
+            return;
+        }
         _Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
     };
     /**
@@ -140093,6 +140191,20 @@ var GPUParticleSystem = /** @class */ (function (_super) {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(GPUParticleSystem.prototype, "isLocal", {
+        /**
+         * Specifies if the particles are updated in emitter local space or world space.
+         * This is always false for GPU particles
+         */
+        get: function () {
+            return false;
+        },
+        set: function (value) {
+            // Ignore
+        },
+        enumerable: true,
+        configurable: true
+    });
     /**
      * Is this system ready to be used/rendered
      * @return true if the system is ready
@@ -141899,6 +142011,10 @@ var ParticleSystem = /** @class */ (function (_super) {
          * If the particle systems emitter should be disposed when the particle system is disposed
          */
         _this._disposeEmitterOnDispose = false;
+        /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        _this.isLocal = false;
         // start of sub system methods
         /**
          * "Recycles" one of the particle by copying it back to the "stock" of particles and removing it from the active list.
@@ -141971,6 +142087,10 @@ var ParticleSystem = /** @class */ (function (_super) {
                 noiseTextureSize = _this.noiseTexture.getSize();
                 noiseTextureData = (_this.noiseTexture.getContent());
             }
+            var worldMatrix = null;
+            if (_this.isLocal && _this.emitter && _this.emitter.getWorldMatrix) {
+                worldMatrix = _this.emitter.getWorldMatrix();
+            }
             var _loop_1 = function () {
                 particle = particles[index];
                 var scaledUpdateSpeed = _this._scaledUpdateSpeed;
@@ -142055,7 +142175,13 @@ var ParticleSystem = /** @class */ (function (_super) {
                         _this._scaledDirection.scaleInPlace(1.0 - drag);
                     });
                 }
-                particle.position.addInPlace(_this._scaledDirection);
+                if (worldMatrix) {
+                    particle._localPosition.addInPlace(_this._scaledDirection);
+                    _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(particle._localPosition, worldMatrix, particle.position);
+                }
+                else {
+                    particle.position.addInPlace(_this._scaledDirection);
+                }
                 // Noise
                 if (noiseTextureData && noiseTextureSize && particle._randomNoiseCoordinates1) {
                     var fetchedColorR = _this._fetchR(particle._randomNoiseCoordinates1.x, particle._randomNoiseCoordinates1.y, noiseTextureSize.width, noiseTextureSize.height, noiseTextureData);
@@ -142865,6 +142991,10 @@ var ParticleSystem = /** @class */ (function (_super) {
             this._emitterWorldMatrix = _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Matrix"].Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);
         }
         this.updateFunction(this._particles);
+        var worldMatrix = null;
+        if (this.isLocal && this.emitter && this.emitter.getWorldMatrix) {
+            worldMatrix = this.emitter.getWorldMatrix();
+        }
         // Add new ones
         var particle;
         var _loop_2 = function () {
@@ -142894,13 +143024,22 @@ var ParticleSystem = /** @class */ (function (_super) {
                 this_1.startPositionFunction(this_1._emitterWorldMatrix, particle.position, particle);
             }
             else {
-                this_1.particleEmitterType.startPositionFunction(this_1._emitterWorldMatrix, particle.position, particle);
+                this_1.particleEmitterType.startPositionFunction(this_1._emitterWorldMatrix, particle.position, particle, this_1.isLocal);
+            }
+            if (worldMatrix) {
+                if (!particle._localPosition) {
+                    particle._localPosition = particle.position.clone();
+                }
+                else {
+                    particle._localPosition.copyFrom(particle.position);
+                }
+                _Maths_math_vector__WEBPACK_IMPORTED_MODULE_3__["Vector3"].TransformCoordinatesToRef(particle._localPosition, worldMatrix, particle.position);
             }
             if (this_1.startDirectionFunction) {
                 this_1.startDirectionFunction(this_1._emitterWorldMatrix, particle.direction, particle);
             }
             else {
-                this_1.particleEmitterType.startDirectionFunction(this_1._emitterWorldMatrix, particle.direction, particle);
+                this_1.particleEmitterType.startDirectionFunction(this_1._emitterWorldMatrix, particle.direction, particle, this_1.isLocal);
             }
             if (emitPower === 0) {
                 if (!particle._initialDirection) {

Plik diff jest za duży
+ 1 - 1
dist/preview release/babylon.max.js.map


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

@@ -11861,6 +11861,10 @@ declare module "babylonjs/Particles/particleSystem" {
         * The current active Sub-systems, this property is used by the root particle system only.
         */
         activeSubSystems: Array<ParticleSystem>;
+        /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
         private _rootParticleSystem;
         /**
          * Gets the current list of active particles
@@ -12285,6 +12289,8 @@ declare module "babylonjs/Particles/particle" {
         _randomNoiseCoordinates1: Vector3;
         /** @hidden */
         _randomNoiseCoordinates2: Vector3;
+        /** @hidden */
+        _localPosition?: Vector3;
         /**
          * Creates a new instance Particle
          * @param particleSystem the particle system the particle belongs to
@@ -12327,15 +12333,17 @@ declare module "babylonjs/Particles/EmitterTypes/IParticleEmitterType" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12404,15 +12412,17 @@ declare module "babylonjs/Particles/EmitterTypes/boxParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12498,15 +12508,17 @@ declare module "babylonjs/Particles/EmitterTypes/coneParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12594,15 +12606,17 @@ declare module "babylonjs/Particles/EmitterTypes/cylinderParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12749,15 +12763,17 @@ declare module "babylonjs/Particles/EmitterTypes/hemisphericParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12817,15 +12833,17 @@ declare module "babylonjs/Particles/EmitterTypes/pointParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12904,15 +12922,17 @@ declare module "babylonjs/Particles/EmitterTypes/sphereParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -13040,15 +13060,17 @@ declare module "babylonjs/Particles/EmitterTypes/customParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -13123,15 +13145,17 @@ declare module "babylonjs/Particles/EmitterTypes/meshParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -13394,6 +13418,10 @@ declare module "babylonjs/Particles/IParticleSystem" {
          */
         disposeOnStop: boolean;
         /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
+        /**
          * Gets the maximum number of particles active at the same time.
          * @returns The max number of active particles.
          */
@@ -65618,6 +65646,12 @@ declare module "babylonjs/Particles/gpuParticleSystem" {
         set activeParticleCount(value: number);
         private _preWarmDone;
         /**
+         * Specifies if the particles are updated in emitter local space or world space.
+         * This is always false for GPU particles
+         */
+        get isLocal(): boolean;
+        set isLocal(value: boolean);
+        /**
          * Is this system ready to be used/rendered
          * @return true if the system is ready
          */
@@ -84834,6 +84868,10 @@ declare module BABYLON {
         * The current active Sub-systems, this property is used by the root particle system only.
         */
         activeSubSystems: Array<ParticleSystem>;
+        /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
         private _rootParticleSystem;
         /**
          * Gets the current list of active particles
@@ -85252,6 +85290,8 @@ declare module BABYLON {
         _randomNoiseCoordinates1: Vector3;
         /** @hidden */
         _randomNoiseCoordinates2: Vector3;
+        /** @hidden */
+        _localPosition?: Vector3;
         /**
          * Creates a new instance Particle
          * @param particleSystem the particle system the particle belongs to
@@ -85290,15 +85330,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85363,15 +85405,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85453,15 +85497,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85545,15 +85591,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85696,15 +85744,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85760,15 +85810,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85843,15 +85895,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85974,15 +86028,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -86051,15 +86107,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -86301,6 +86359,10 @@ declare module BABYLON {
          */
         disposeOnStop: boolean;
         /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
+        /**
          * Gets the maximum number of particles active at the same time.
          * @returns The max number of active particles.
          */
@@ -135642,6 +135704,12 @@ declare module BABYLON {
         set activeParticleCount(value: number);
         private _preWarmDone;
         /**
+         * Specifies if the particles are updated in emitter local space or world space.
+         * This is always false for GPU particles
+         */
+        get isLocal(): boolean;
+        set isLocal(value: boolean);
+        /**
          * Is this system ready to be used/rendered
          * @return true if the system is ready
          */

+ 52 - 18
dist/preview release/documentation.d.ts

@@ -11601,6 +11601,10 @@ declare module BABYLON {
         * The current active Sub-systems, this property is used by the root particle system only.
         */
         activeSubSystems: Array<ParticleSystem>;
+        /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
         private _rootParticleSystem;
         /**
          * Gets the current list of active particles
@@ -12019,6 +12023,8 @@ declare module BABYLON {
         _randomNoiseCoordinates1: Vector3;
         /** @hidden */
         _randomNoiseCoordinates2: Vector3;
+        /** @hidden */
+        _localPosition?: Vector3;
         /**
          * Creates a new instance Particle
          * @param particleSystem the particle system the particle belongs to
@@ -12057,15 +12063,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12130,15 +12138,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12220,15 +12230,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12312,15 +12324,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12463,15 +12477,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12527,15 +12543,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12610,15 +12628,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12741,15 +12761,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12818,15 +12840,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -13068,6 +13092,10 @@ declare module BABYLON {
          */
         disposeOnStop: boolean;
         /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
+        /**
          * Gets the maximum number of particles active at the same time.
          * @returns The max number of active particles.
          */
@@ -62409,6 +62437,12 @@ declare module BABYLON {
         set activeParticleCount(value: number);
         private _preWarmDone;
         /**
+         * Specifies if the particles are updated in emitter local space or world space.
+         * This is always false for GPU particles
+         */
+        get isLocal(): boolean;
+        set isLocal(value: boolean);
+        /**
          * Is this system ready to be used/rendered
          * @return true if the system is ready
          */

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

@@ -1273,7 +1273,9 @@ declare module NODEEDITOR {
     export class PreviewAreaComponent extends React.Component<IPreviewAreaComponentProps, {
         isLoading: boolean;
     }> {
+        private _onIsLoadingChangedObserver;
         constructor(props: IPreviewAreaComponentProps);
+        componentWillUnmount(): void;
         changeBackFaceCulling(value: boolean): void;
         changeDepthPrePass(value: boolean): void;
         render(): JSX.Element;

Plik diff jest za duży
+ 2 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.js


+ 35 - 32
dist/preview release/nodeEditor/babylon.nodeEditor.max.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-node-editor"] = factory(require("babylonjs"));
 	else
 		root["NODEEDITOR"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_observable__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -51129,7 +51129,7 @@ module.exports = function(module) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BlockTools", function() { return BlockTools; });
-/* harmony import */ var babylonjs_Materials_Node_Blocks_Fragment_discardBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/Fragment/discardBlock */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Blocks_Fragment_discardBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/Fragment/discardBlock */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Blocks_Fragment_discardBlock__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Blocks_Fragment_discardBlock__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -51961,9 +51961,12 @@ var PreviewAreaComponent = /** @class */ (function (_super) {
     function PreviewAreaComponent(props) {
         var _this = _super.call(this, props) || this;
         _this.state = { isLoading: true };
-        _this.props.globalState.onIsLoadingChanged.add(function (state) { return _this.setState({ isLoading: state }); });
+        _this._onIsLoadingChangedObserver = _this.props.globalState.onIsLoadingChanged.add(function (state) { return _this.setState({ isLoading: state }); });
         return _this;
     }
+    PreviewAreaComponent.prototype.componentWillUnmount = function () {
+        this.props.globalState.onIsLoadingChanged.remove(this._onIsLoadingChangedObserver);
+    };
     PreviewAreaComponent.prototype.changeBackFaceCulling = function (value) {
         this.props.globalState.backFaceCulling = value;
         _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].StoreBoolean("BackFaceCulling", value);
@@ -52026,7 +52029,7 @@ var PreviewAreaComponent = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PreviewManager", function() { return PreviewManager; });
-/* harmony import */ var babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/nodeMaterial */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/nodeMaterial */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_nodeMaterial__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _previewMeshType__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./previewMeshType */ "./components/preview/previewMeshType.ts");
 /* harmony import */ var _log_logComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../log/logComponent */ "./components/log/logComponent.tsx");
@@ -52331,7 +52334,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 react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__);
 /* harmony import */ var _previewMeshType__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./previewMeshType */ "./components/preview/previewMeshType.ts");
 /* harmony import */ var _dataStorage__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../dataStorage */ "./dataStorage.ts");
@@ -52860,7 +52863,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../sharedComponents/lineContainerComponent */ "./sharedComponents/lineContainerComponent.tsx");
 /* harmony import */ var _stringTools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../stringTools */ "./stringTools.ts");
 /* harmony import */ var _sharedComponents_fileButtonLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../sharedComponents/fileButtonLineComponent */ "./sharedComponents/fileButtonLineComponent.tsx");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_6__);
 /* harmony import */ var _serializationTools__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../../serializationTools */ "./serializationTools.ts");
 /* harmony import */ var _sharedComponents_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../../sharedComponents/checkBoxLineComponent */ "./sharedComponents/checkBoxLineComponent.tsx");
@@ -53257,7 +53260,7 @@ var GradientDisplayManager = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputDisplayManager", function() { return InputDisplayManager; });
-/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialSystemValues */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialSystemValues */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Enums_nodeMaterialSystemValues__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _blockTools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../blockTools */ "./blockTools.ts");
 /* harmony import */ var _stringTools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../stringTools */ "./stringTools.ts");
@@ -53474,7 +53477,7 @@ var RemapDisplayManager = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextureDisplayManager", function() { return TextureDisplayManager; });
-/* harmony import */ var babylonjs_Materials_Node_Blocks_Dual_textureBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/Dual/textureBlock */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Blocks_Dual_textureBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/Dual/textureBlock */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Blocks_Dual_textureBlock__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Blocks_Dual_textureBlock__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _sharedComponents_textureLineComponent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../sharedComponents/textureLineComponent */ "./sharedComponents/textureLineComponent.tsx");
 
@@ -53540,7 +53543,7 @@ var TextureDisplayManager = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TrigonometryDisplayManager", function() { return TrigonometryDisplayManager; });
-/* harmony import */ var babylonjs_Materials_Node_Blocks_trigonometryBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/trigonometryBlock */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Blocks_trigonometryBlock__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/trigonometryBlock */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Blocks_trigonometryBlock__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Blocks_trigonometryBlock__WEBPACK_IMPORTED_MODULE_0__);
 
 var TrigonometryDisplayManager = /** @class */ (function () {
@@ -53660,7 +53663,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 react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_2__);
 /* harmony import */ var _graphNode__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./graphNode */ "./diagram/graphNode.ts");
 /* harmony import */ var dagre__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! dagre */ "../../node_modules/dagre/index.js");
@@ -54418,7 +54421,7 @@ var GraphCanvasComponent = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GraphFrame", function() { return GraphFrame; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* 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 _nodePort__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./nodePort */ "./diagram/nodePort.ts");
 /* harmony import */ var _serializationTools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../serializationTools */ "./serializationTools.ts");
@@ -55579,7 +55582,7 @@ var GraphNode = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodeLink", function() { return NodeLink; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 
 var NodeLink = /** @class */ (function () {
@@ -55733,7 +55736,7 @@ var NodeLink = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "NodePort", function() { return NodePort; });
 /* harmony import */ var _blockTools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../blockTools */ "./blockTools.ts");
-/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -56027,7 +56030,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../sharedComponents/lineContainerComponent */ "./sharedComponents/lineContainerComponent.tsx");
-/* harmony import */ var babylonjs_Materials_Node_Blocks_gradientBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/gradientBlock */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Blocks_gradientBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/gradientBlock */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Blocks_gradientBlock__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Blocks_gradientBlock__WEBPACK_IMPORTED_MODULE_3__);
 /* harmony import */ var _gradientStepComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./gradientStepComponent */ "./diagram/properties/gradientStepComponent.tsx");
 /* harmony import */ var _sharedComponents_buttonLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../sharedComponents/buttonLineComponent */ "./sharedComponents/buttonLineComponent.tsx");
@@ -56112,7 +56115,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @fortawesome/react-fontawesome */ "../../node_modules/@fortawesome/react-fontawesome/index.es.js");
 /* harmony import */ var _fortawesome_free_solid_svg_icons__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @fortawesome/free-solid-svg-icons */ "../../node_modules/@fortawesome/free-solid-svg-icons/index.es.js");
-/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_4__);
 
 
@@ -56181,7 +56184,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _components_propertyTab_properties_matrixPropertyTabComponent__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../components/propertyTab/properties/matrixPropertyTabComponent */ "./components/propertyTab/properties/matrixPropertyTabComponent.tsx");
 /* harmony import */ var _sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../sharedComponents/lineContainerComponent */ "./sharedComponents/lineContainerComponent.tsx");
 /* harmony import */ var _sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../sharedComponents/optionsLineComponent */ "./sharedComponents/optionsLineComponent.tsx");
-/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_12__);
 /* harmony import */ var _genericNodePropertyComponent__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./genericNodePropertyComponent */ "./diagram/properties/genericNodePropertyComponent.tsx");
 /* harmony import */ var _sharedComponents_textInputLineComponent__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../../sharedComponents/textInputLineComponent */ "./sharedComponents/textInputLineComponent.tsx");
@@ -56604,7 +56607,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _sharedComponents_fileButtonLineComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../sharedComponents/fileButtonLineComponent */ "./sharedComponents/fileButtonLineComponent.tsx");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_3__);
 /* harmony import */ var _sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../sharedComponents/lineContainerComponent */ "./sharedComponents/lineContainerComponent.tsx");
 /* harmony import */ var _sharedComponents_textInputLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../sharedComponents/textInputLineComponent */ "./sharedComponents/textInputLineComponent.tsx");
@@ -56913,7 +56916,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _sharedComponents_lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../sharedComponents/lineContainerComponent */ "./sharedComponents/lineContainerComponent.tsx");
 /* harmony import */ var _sharedComponents_optionsLineComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../sharedComponents/optionsLineComponent */ "./sharedComponents/optionsLineComponent.tsx");
-/* harmony import */ var babylonjs_Materials_Node_Blocks_trigonometryBlock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/trigonometryBlock */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Blocks_trigonometryBlock__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/trigonometryBlock */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Blocks_trigonometryBlock__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Blocks_trigonometryBlock__WEBPACK_IMPORTED_MODULE_4__);
 /* harmony import */ var _genericNodePropertyComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./genericNodePropertyComponent */ "./diagram/properties/genericNodePropertyComponent.tsx");
 
@@ -57073,7 +57076,7 @@ PropertyLedger.RegisteredControls["TrigonometryBlock"] = _properties_trigonometr
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GlobalState", function() { return GlobalState; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* 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 _components_preview_previewMeshType__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./components/preview/previewMeshType */ "./components/preview/previewMeshType.ts");
 /* harmony import */ var _dataStorage__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./dataStorage */ "./dataStorage.ts");
@@ -57112,9 +57115,9 @@ var GlobalState = /** @class */ (function () {
         this.directionalLight0 = _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].ReadBoolean("DirectionalLight0", false);
         this.directionalLight1 = _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].ReadBoolean("DirectionalLight1", false);
         this.controlCamera = _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].ReadBoolean("ControlCamera", true);
-        var r = _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].ReadNumber("BackgroundColorR", 32);
-        var g = _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].ReadNumber("BackgroundColorG", 25);
-        var b = _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].ReadNumber("BackgroundColorB", 64);
+        var r = _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].ReadNumber("BackgroundColorR", 0.12549019607843137);
+        var g = _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].ReadNumber("BackgroundColorG", 0.09803921568627451);
+        var b = _dataStorage__WEBPACK_IMPORTED_MODULE_2__["DataStorage"].ReadNumber("BackgroundColorB", 0.25098039215686274);
         this.backgroundColor = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Color4"](r, g, b, 1.0);
     }
     return GlobalState;
@@ -57142,7 +57145,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _portal__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./portal */ "./portal.tsx");
 /* harmony import */ var _components_log_logComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/log/logComponent */ "./components/log/logComponent.tsx");
 /* harmony import */ var _dataStorage__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./dataStorage */ "./dataStorage.ts");
-/* harmony import */ var babylonjs_Materials_Node_Blocks_Input_inputBlock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/Input/inputBlock */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Blocks_Input_inputBlock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! babylonjs/Materials/Node/Blocks/Input/inputBlock */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Blocks_Input_inputBlock__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Blocks_Input_inputBlock__WEBPACK_IMPORTED_MODULE_7__);
 /* harmony import */ var _sharedComponents_messageDialog__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./sharedComponents/messageDialog */ "./sharedComponents/messageDialog.tsx");
 /* harmony import */ var _blockTools__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./blockTools */ "./blockTools.ts");
@@ -57998,7 +58001,7 @@ var Portal = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SerializationTools", function() { return SerializationTools; });
-/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Textures/texture */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Textures/texture */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Textures_texture__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _dataStorage__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./dataStorage */ "./dataStorage.ts");
 
@@ -58168,7 +58171,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 react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__);
 /* harmony import */ var _numericInputComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./numericInputComponent */ "./sharedComponents/numericInputComponent.tsx");
 /* harmony import */ var _fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @fortawesome/react-fontawesome */ "../../node_modules/@fortawesome/react-fontawesome/index.es.js");
@@ -58315,7 +58318,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 react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math.color */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_color__WEBPACK_IMPORTED_MODULE_2__);
 /* harmony import */ var _numericInputComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./numericInputComponent */ "./sharedComponents/numericInputComponent.tsx");
 /* harmony import */ var _fortawesome_react_fontawesome__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @fortawesome/react-fontawesome */ "../../node_modules/@fortawesome/react-fontawesome/index.es.js");
@@ -58702,7 +58705,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 react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_2__);
 /* harmony import */ var _vector4LineComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./vector4LineComponent */ "./sharedComponents/vector4LineComponent.tsx");
 /* harmony import */ var _optionsLineComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./optionsLineComponent */ "./sharedComponents/optionsLineComponent.tsx");
@@ -59126,7 +59129,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 react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -59358,7 +59361,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 react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var babylonjs_Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Engines/constants */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Engines_constants__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Engines/constants */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Engines_constants__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Engines_constants__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -59836,7 +59839,7 @@ var Vector4LineComponent = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StringTools", function() { return StringTools; });
-/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Materials/Textures/texture");
+/* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_Node_Enums_nodeMaterialBlockConnectionPointTypes__WEBPACK_IMPORTED_MODULE_0__);
 
 var StringTools = /** @class */ (function () {
@@ -59935,14 +59938,14 @@ var StringTools = /** @class */ (function () {
 
 /***/ }),
 
-/***/ "babylonjs/Materials/Textures/texture":
+/***/ "babylonjs/Misc/observable":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_Textures_texture__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_observable__;
 
 /***/ })
 

Plik diff jest za duży
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


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

@@ -1535,7 +1535,9 @@ declare module "babylonjs-node-editor/components/preview/previewAreaComponent" {
     export class PreviewAreaComponent extends React.Component<IPreviewAreaComponentProps, {
         isLoading: boolean;
     }> {
+        private _onIsLoadingChangedObserver;
         constructor(props: IPreviewAreaComponentProps);
+        componentWillUnmount(): void;
         changeBackFaceCulling(value: boolean): void;
         changeDepthPrePass(value: boolean): void;
         render(): JSX.Element;
@@ -2929,7 +2931,9 @@ declare module NODEEDITOR {
     export class PreviewAreaComponent extends React.Component<IPreviewAreaComponentProps, {
         isLoading: boolean;
     }> {
+        private _onIsLoadingChangedObserver;
         constructor(props: IPreviewAreaComponentProps);
+        componentWillUnmount(): void;
         changeBackFaceCulling(value: boolean): void;
         changeDepthPrePass(value: boolean): void;
         render(): JSX.Element;

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

@@ -11861,6 +11861,10 @@ declare module "babylonjs/Particles/particleSystem" {
         * The current active Sub-systems, this property is used by the root particle system only.
         */
         activeSubSystems: Array<ParticleSystem>;
+        /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
         private _rootParticleSystem;
         /**
          * Gets the current list of active particles
@@ -12285,6 +12289,8 @@ declare module "babylonjs/Particles/particle" {
         _randomNoiseCoordinates1: Vector3;
         /** @hidden */
         _randomNoiseCoordinates2: Vector3;
+        /** @hidden */
+        _localPosition?: Vector3;
         /**
          * Creates a new instance Particle
          * @param particleSystem the particle system the particle belongs to
@@ -12327,15 +12333,17 @@ declare module "babylonjs/Particles/EmitterTypes/IParticleEmitterType" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12404,15 +12412,17 @@ declare module "babylonjs/Particles/EmitterTypes/boxParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12498,15 +12508,17 @@ declare module "babylonjs/Particles/EmitterTypes/coneParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12594,15 +12606,17 @@ declare module "babylonjs/Particles/EmitterTypes/cylinderParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12749,15 +12763,17 @@ declare module "babylonjs/Particles/EmitterTypes/hemisphericParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12817,15 +12833,17 @@ declare module "babylonjs/Particles/EmitterTypes/pointParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -12904,15 +12922,17 @@ declare module "babylonjs/Particles/EmitterTypes/sphereParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -13040,15 +13060,17 @@ declare module "babylonjs/Particles/EmitterTypes/customParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -13123,15 +13145,17 @@ declare module "babylonjs/Particles/EmitterTypes/meshParticleEmitter" {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -13394,6 +13418,10 @@ declare module "babylonjs/Particles/IParticleSystem" {
          */
         disposeOnStop: boolean;
         /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
+        /**
          * Gets the maximum number of particles active at the same time.
          * @returns The max number of active particles.
          */
@@ -65618,6 +65646,12 @@ declare module "babylonjs/Particles/gpuParticleSystem" {
         set activeParticleCount(value: number);
         private _preWarmDone;
         /**
+         * Specifies if the particles are updated in emitter local space or world space.
+         * This is always false for GPU particles
+         */
+        get isLocal(): boolean;
+        set isLocal(value: boolean);
+        /**
          * Is this system ready to be used/rendered
          * @return true if the system is ready
          */
@@ -84834,6 +84868,10 @@ declare module BABYLON {
         * The current active Sub-systems, this property is used by the root particle system only.
         */
         activeSubSystems: Array<ParticleSystem>;
+        /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
         private _rootParticleSystem;
         /**
          * Gets the current list of active particles
@@ -85252,6 +85290,8 @@ declare module BABYLON {
         _randomNoiseCoordinates1: Vector3;
         /** @hidden */
         _randomNoiseCoordinates2: Vector3;
+        /** @hidden */
+        _localPosition?: Vector3;
         /**
          * Creates a new instance Particle
          * @param particleSystem the particle system the particle belongs to
@@ -85290,15 +85330,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85363,15 +85405,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85453,15 +85497,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85545,15 +85591,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85696,15 +85744,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85760,15 +85810,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85843,15 +85895,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -85974,15 +86028,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -86051,15 +86107,17 @@ declare module BABYLON {
          * @param worldMatrix is the world matrix of the particle system
          * @param directionToUpdate is the direction vector to update with the result
          * @param particle is the particle we are computed the direction for
+         * @param isLocal defines if the direction should be set in local space
          */
-        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+        startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Called by the particle System when the position is computed for the created particle.
          * @param worldMatrix is the world matrix of the particle system
          * @param positionToUpdate is the position vector to update with the result
          * @param particle is the particle we are computed the position for
+         * @param isLocal defines if the position should be set in local space
          */
-        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+        startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
         /**
          * Clones the current emitter and returns a copy of it
          * @returns the new emitter
@@ -86301,6 +86359,10 @@ declare module BABYLON {
          */
         disposeOnStop: boolean;
         /**
+         * Specifies if the particles are updated in emitter local space or world space
+         */
+        isLocal: boolean;
+        /**
          * Gets the maximum number of particles active at the same time.
          * @returns The max number of active particles.
          */
@@ -135642,6 +135704,12 @@ declare module BABYLON {
         set activeParticleCount(value: number);
         private _preWarmDone;
         /**
+         * Specifies if the particles are updated in emitter local space or world space.
+         * This is always false for GPU particles
+         */
+        get isLocal(): boolean;
+        set isLocal(value: boolean);
+        /**
          * Is this system ready to be used/rendered
          * @return true if the system is ready
          */

Plik diff jest za duży
+ 11 - 11
dist/preview release/viewer/babylon.viewer.js


Plik diff jest za duży
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -240,6 +240,7 @@
 
 ### Particles
 
+- Added `particleSystem.isLocal` for CPU particles to let the particles live in emitter local space. [Doc](https://doc.babylonjs.com/babylon101/particles#local-space) ([Deltakosh](https://github.com/deltakosh/))
 - Added the feature `expandable` to the Solid Particle System ([jerome](https://github.com/jbousquie/))
 - Added the feature `removeParticles()` to the Solid Particle System ([jerome](https://github.com/jbousquie/))
 - Added the feature "storable particles" and `insertParticlesFromArray()` to the Solid Particle System ([jerome](https://github.com/jbousquie/))

+ 2 - 1
nodeEditor/src/components/preview/previewAreaComponent.tsx

@@ -2,7 +2,8 @@
 import * as React from "react";
 import { GlobalState } from '../../globalState';
 import { DataStorage } from '../../dataStorage';
-import { Nullable, Observer } from 'babylonjs';
+import { Observer } from 'babylonjs/Misc/observable';
+import { Nullable } from 'babylonjs/types';
 
 const doubleSided: string = require("./svgs/doubleSided.svg");
 const depthPass: string = require("./svgs/depthPass.svg");

+ 6 - 0
src/Engines/Extensions/engine.views.ts

@@ -63,6 +63,12 @@ Engine.prototype.registerView = function(canvas: HTMLCanvasElement, camera?: Cam
         }
     }
 
+    let masterCanvas = this.getRenderingCanvas();
+    if (masterCanvas) {
+        canvas.width = masterCanvas.width;
+        canvas.height = masterCanvas.height;
+    }
+
     let newView = {target: canvas, camera: camera};
     this.views.push(newView);
 

+ 4 - 2
src/Particles/EmitterTypes/IParticleEmitterType.ts

@@ -12,16 +12,18 @@ export interface IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void;
+    startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
 
     /**
      * Called by the particle System when the position is computed for the created particle.
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void;
+    startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void;
 
     /**
      * Clones the current emitter and returns a copy of it

+ 18 - 2
src/Particles/EmitterTypes/boxParticleEmitter.ts

@@ -40,12 +40,20 @@ export class BoxParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var randX = Scalar.RandomRange(this.direction1.x, this.direction2.x);
         var randY = Scalar.RandomRange(this.direction1.y, this.direction2.y);
         var randZ = Scalar.RandomRange(this.direction1.z, this.direction2.z);
 
+        if (isLocal) {
+            directionToUpdate.x = randX;
+            directionToUpdate.y = randY;
+            directionToUpdate.z = randZ;
+            return;
+        }
+
         Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
     }
 
@@ -54,12 +62,20 @@ export class BoxParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var randX = Scalar.RandomRange(this.minEmitBox.x, this.maxEmitBox.x);
         var randY = Scalar.RandomRange(this.minEmitBox.y, this.maxEmitBox.y);
         var randZ = Scalar.RandomRange(this.minEmitBox.z, this.maxEmitBox.z);
 
+        if (isLocal) {
+            positionToUpdate.x = randX;
+            positionToUpdate.y = randY;
+            positionToUpdate.z = randZ;
+            return;
+        }
+
         Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
     }
 

+ 22 - 2
src/Particles/EmitterTypes/coneParticleEmitter.ts

@@ -80,9 +80,16 @@ export class ConeParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+    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);
         }
         else {
@@ -96,6 +103,11 @@ export class ConeParticleEmitter implements IParticleEmitterType {
             direction.z += randZ;
             direction.normalize();
 
+            if (isLocal) {
+                directionToUpdate.copyFrom(direction);
+                return;
+            }
+
             Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
         }
     }
@@ -105,8 +117,9 @@ export class ConeParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+    startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var s = Scalar.RandomRange(0, Math.PI * 2);
         var h: number;
 
@@ -124,6 +137,13 @@ export class ConeParticleEmitter implements IParticleEmitterType {
         var randZ = radius * Math.cos(s);
         var randY = h * this._height;
 
+        if (isLocal) {
+            positionToUpdate.x = randX;
+            positionToUpdate.y = randY;
+            positionToUpdate.z = randZ;
+            return;
+        }
+
         Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
     }
 

+ 14 - 2
src/Particles/EmitterTypes/customParticleEmitter.ts

@@ -33,8 +33,9 @@ export class CustomParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         let tmpVector = TmpVectors.Vector3[0];
 
         if (this.particleDestinationGenerator) {
@@ -49,6 +50,11 @@ export class CustomParticleEmitter implements IParticleEmitterType {
             tmpVector.set(0, 0, 0);
         }
 
+        if (isLocal) {
+            directionToUpdate.copyFrom(tmpVector);
+            return;
+        }
+
         Vector3.TransformNormalToRef(tmpVector, worldMatrix, directionToUpdate);
     }
 
@@ -57,8 +63,9 @@ export class CustomParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         let tmpVector = TmpVectors.Vector3[0];
 
         if (this.particlePositionGenerator) {
@@ -67,6 +74,11 @@ export class CustomParticleEmitter implements IParticleEmitterType {
             tmpVector.set(0, 0, 0);
         }
 
+        if (isLocal) {
+            positionToUpdate.copyFrom(tmpVector);
+            return;
+        }
+
         Vector3.TransformCoordinatesToRef(tmpVector, worldMatrix, positionToUpdate);
     }
 

+ 14 - 2
src/Particles/EmitterTypes/cylinderParticleEmitter.ts

@@ -40,8 +40,9 @@ export class CylinderParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
         var randY = Scalar.RandomRange(-this.directionRandomizer / 2, this.directionRandomizer / 2);
 
@@ -53,6 +54,11 @@ export class CylinderParticleEmitter implements IParticleEmitterType {
         direction.z = Math.cos(angle);
         direction.normalize();
 
+        if (isLocal) {
+            directionToUpdate.copyFrom(direction);
+            return;
+        }
+
         Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
     }
 
@@ -61,8 +67,9 @@ export class CylinderParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var yPos = Scalar.RandomRange(-this.height / 2, this.height / 2);
         var angle = Scalar.RandomRange(0, 2 * Math.PI);
 
@@ -72,6 +79,11 @@ export class CylinderParticleEmitter implements IParticleEmitterType {
         var xPos = positionRadius * Math.cos(angle);
         var zPos = positionRadius * Math.sin(angle);
 
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(xPos, yPos, zPos);
+            return;
+        }
+
         Vector3.TransformCoordinatesFromFloatsToRef(xPos, yPos, zPos, worldMatrix, positionToUpdate);
     }
 

+ 15 - 2
src/Particles/EmitterTypes/hemisphericParticleEmitter.ts

@@ -35,8 +35,9 @@ export class HemisphericParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
         var randX = Scalar.RandomRange(0, this.directionRandomizer);
         var randY = Scalar.RandomRange(0, this.directionRandomizer);
@@ -46,6 +47,11 @@ export class HemisphericParticleEmitter implements IParticleEmitterType {
         direction.z += randZ;
         direction.normalize();
 
+        if (isLocal) {
+            directionToUpdate.copyFrom(direction);
+            return;
+        }
+
         Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
     }
 
@@ -54,8 +60,9 @@ export class HemisphericParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var randRadius = this.radius - Scalar.RandomRange(0, this.radius * this.radiusRange);
         var v = Scalar.RandomRange(0, 1.0);
         var phi = Scalar.RandomRange(0, 2 * Math.PI);
@@ -63,6 +70,12 @@ export class HemisphericParticleEmitter implements IParticleEmitterType {
         var randX = randRadius * Math.cos(phi) * Math.sin(theta);
         var randY = randRadius * Math.cos(theta);
         var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
+
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(randX, Math.abs(randY), randZ);
+            return;
+        }
+
         Vector3.TransformCoordinatesFromFloatsToRef(randX, Math.abs(randY), randZ, worldMatrix, positionToUpdate);
     }
 

+ 14 - 3
src/Particles/EmitterTypes/meshParticleEmitter.ts

@@ -52,8 +52,9 @@ export class MeshParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         if (this.useMeshNormalsForDirection && this._normals) {
             Vector3.TransformNormalToRef(this._storedNormal, worldMatrix, directionToUpdate);
             return;
@@ -63,6 +64,11 @@ export class MeshParticleEmitter implements IParticleEmitterType {
         var randY = Scalar.RandomRange(this.direction1.y, this.direction2.y);
         var randZ = Scalar.RandomRange(this.direction1.z, this.direction2.z);
 
+        if (isLocal) {
+            directionToUpdate.copyFromFloats(randX, randY, randZ);
+            return;
+        }
+
         Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
     }
 
@@ -71,8 +77,9 @@ export class MeshParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         if (!this._indices || !this._positions) {
             return;
         }
@@ -98,7 +105,11 @@ export class MeshParticleEmitter implements IParticleEmitterType {
         randomVertex.y = bu * vertexA.y + bv * vertexB.y + bw * vertexC.y;
         randomVertex.z = bu * vertexA.z + bv * vertexB.z + bw * vertexC.z;
 
-        Vector3.TransformCoordinatesFromFloatsToRef(randomVertex.x, randomVertex.y, randomVertex.z, worldMatrix, positionToUpdate);
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(randomVertex.x, randomVertex.y, randomVertex.z);
+        } else {
+            Vector3.TransformCoordinatesFromFloatsToRef(randomVertex.x, randomVertex.y, randomVertex.z, worldMatrix, positionToUpdate);
+        }
 
         if (this.useMeshNormalsForDirection && this._normals) {
             Vector3.FromArrayToRef(this._normals, faceIndexA * 3, vertexA);

+ 13 - 2
src/Particles/EmitterTypes/pointParticleEmitter.ts

@@ -31,12 +31,18 @@ export class PointParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var randX = Scalar.RandomRange(this.direction1.x, this.direction2.x);
         var randY = Scalar.RandomRange(this.direction1.y, this.direction2.y);
         var randZ = Scalar.RandomRange(this.direction1.z, this.direction2.z);
 
+        if (isLocal) {
+            directionToUpdate.copyFromFloats(randX, randY, randZ);
+            return;
+        }
+
         Vector3.TransformNormalFromFloatsToRef(randX, randY, randZ, worldMatrix, directionToUpdate);
     }
 
@@ -45,8 +51,13 @@ export class PointParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(0, 0, 0);
+            return;
+        }
         Vector3.TransformCoordinatesFromFloatsToRef(0, 0, 0, worldMatrix, positionToUpdate);
     }
 

+ 15 - 2
src/Particles/EmitterTypes/sphereParticleEmitter.ts

@@ -35,8 +35,9 @@ export class SphereParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param directionToUpdate is the direction vector to update with the result
      * @param particle is the particle we are computed the direction for
+     * @param isLocal defines if the direction should be set in local space
      */
-    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle): void {
+    public startDirectionFunction(worldMatrix: Matrix, directionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var direction = particle.position.subtract(worldMatrix.getTranslation()).normalize();
         var randX = Scalar.RandomRange(0, this.directionRandomizer);
         var randY = Scalar.RandomRange(0, this.directionRandomizer);
@@ -46,6 +47,11 @@ export class SphereParticleEmitter implements IParticleEmitterType {
         direction.z += randZ;
         direction.normalize();
 
+        if (isLocal) {
+            directionToUpdate.copyFrom(direction);
+            return;
+        }
+
         Vector3.TransformNormalFromFloatsToRef(direction.x, direction.y, direction.z, worldMatrix, directionToUpdate);
     }
 
@@ -54,8 +60,9 @@ export class SphereParticleEmitter implements IParticleEmitterType {
      * @param worldMatrix is the world matrix of the particle system
      * @param positionToUpdate is the position vector to update with the result
      * @param particle is the particle we are computed the position for
+     * @param isLocal defines if the position should be set in local space
      */
-    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
+    public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle, isLocal: boolean): void {
         var randRadius = this.radius - Scalar.RandomRange(0, this.radius * this.radiusRange);
         var v = Scalar.RandomRange(0, 1.0);
         var phi = Scalar.RandomRange(0, 2 * Math.PI);
@@ -63,6 +70,12 @@ export class SphereParticleEmitter implements IParticleEmitterType {
         var randX = randRadius * Math.cos(phi) * Math.sin(theta);
         var randY = randRadius * Math.cos(theta);
         var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
+
+        if (isLocal) {
+            positionToUpdate.copyFromFloats(randX, randY, randZ);
+            return;
+        }
+
         Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
     }
 

+ 5 - 0
src/Particles/IParticleSystem.ts

@@ -243,6 +243,11 @@ export interface IParticleSystem {
     disposeOnStop: boolean;
 
     /**
+     * Specifies if the particles are updated in emitter local space or world space
+     */
+    isLocal: boolean;
+
+    /**
      * Gets the maximum number of particles active at the same time.
      * @returns The max number of active particles.
      */

+ 12 - 0
src/Particles/gpuParticleSystem.ts

@@ -120,6 +120,18 @@ export class GPUParticleSystem extends BaseParticleSystem implements IDisposable
     private _preWarmDone = false;
 
     /**
+     * Specifies if the particles are updated in emitter local space or world space.
+     * This is always false for GPU particles
+     */
+    public get isLocal() {
+        return false;
+    }
+
+    public set isLocal(value: boolean) {
+        // Ignore
+    }
+
+    /**
      * Is this system ready to be used/rendered
      * @return true if the system is ready
      */

+ 3 - 0
src/Particles/particle.ts

@@ -137,6 +137,9 @@ export class Particle {
     /** @hidden */
     public _randomNoiseCoordinates2: Vector3;
 
+    /** @hidden */
+    public _localPosition?: Vector3;
+
     /**
      * Creates a new instance Particle
      * @param particleSystem the particle system the particle belongs to

+ 38 - 3
src/Particles/particleSystem.ts

@@ -174,6 +174,11 @@ export class ParticleSystem extends BaseParticleSystem implements IDisposable, I
     */
     public activeSubSystems: Array<ParticleSystem>;
 
+    /**
+     * Specifies if the particles are updated in emitter local space or world space
+     */
+    public isLocal = false;
+
     private _rootParticleSystem: Nullable<ParticleSystem>;
     //end of Sub-emitter
 
@@ -237,6 +242,12 @@ export class ParticleSystem extends BaseParticleSystem implements IDisposable, I
                 noiseTextureData = <Nullable<Uint8Array>>(this.noiseTexture.getContent());
             }
 
+            let worldMatrix: Nullable<Matrix> = null;
+
+            if (this.isLocal && this.emitter && (this.emitter as AbstractMesh).getWorldMatrix) {
+                worldMatrix = (this.emitter as AbstractMesh).getWorldMatrix();
+            }
+
             for (var index = 0; index < particles.length; index++) {
                 var particle = particles[index];
 
@@ -339,7 +350,12 @@ export class ParticleSystem extends BaseParticleSystem implements IDisposable, I
                     });
                 }
 
-                particle.position.addInPlace(this._scaledDirection);
+                if (worldMatrix) {
+                    particle._localPosition!.addInPlace(this._scaledDirection);
+                    Vector3.TransformCoordinatesToRef(particle._localPosition!, worldMatrix, particle.position);
+                } else {
+                    particle.position.addInPlace(this._scaledDirection);
+                }
 
                 // Noise
                 if (noiseTextureData && noiseTextureSize && particle._randomNoiseCoordinates1) {
@@ -1282,6 +1298,12 @@ export class ParticleSystem extends BaseParticleSystem implements IDisposable, I
 
         this.updateFunction(this._particles);
 
+        let worldMatrix: Nullable<Matrix> = null;
+
+        if (this.isLocal && this.emitter && (this.emitter as AbstractMesh).getWorldMatrix) {
+            worldMatrix = (this.emitter as AbstractMesh).getWorldMatrix();
+        }
+
         // Add new ones
         var particle: Particle;
         for (var index = 0; index < newParticles; index++) {
@@ -1315,14 +1337,23 @@ export class ParticleSystem extends BaseParticleSystem implements IDisposable, I
                 this.startPositionFunction(this._emitterWorldMatrix, particle.position, particle);
             }
             else {
-                this.particleEmitterType.startPositionFunction(this._emitterWorldMatrix, particle.position, particle);
+                this.particleEmitterType.startPositionFunction(this._emitterWorldMatrix, particle.position, particle, this.isLocal);
+            }
+
+            if (worldMatrix) {
+                if (!particle._localPosition) {
+                    particle._localPosition = particle.position.clone();
+                } else {
+                    particle._localPosition.copyFrom(particle.position);
+                }
+                Vector3.TransformCoordinatesToRef(particle._localPosition!, worldMatrix, particle.position);
             }
 
             if (this.startDirectionFunction) {
                 this.startDirectionFunction(this._emitterWorldMatrix, particle.direction, particle);
             }
             else {
-                this.particleEmitterType.startDirectionFunction(this._emitterWorldMatrix, particle.direction, particle);
+                this.particleEmitterType.startDirectionFunction(this._emitterWorldMatrix, particle.direction, particle, this.isLocal);
             }
 
             if (emitPower === 0) {
@@ -2075,6 +2106,8 @@ export class ParticleSystem extends BaseParticleSystem implements IDisposable, I
             serializationObject.invertY = particleSystem.particleTexture._invertY;
         }
 
+        serializationObject.isLocal = particleSystem.isLocal;
+
         // Animations
         SerializationHelper.AppendSerializedAnimations(particleSystem, serializationObject);
         serializationObject.beginAnimationOnStart = particleSystem.beginAnimationOnStart;
@@ -2356,6 +2389,8 @@ export class ParticleSystem extends BaseParticleSystem implements IDisposable, I
             particleSystem.emitter = Vector3.FromArray(parsedParticleSystem.emitter);
         }
 
+        particleSystem.isLocal = !!parsedParticleSystem.isLocal;
+
         // Misc.
         if (parsedParticleSystem.renderingGroupId !== undefined) {
             particleSystem.renderingGroupId = parsedParticleSystem.renderingGroupId;