Pārlūkot izejas kodu

Added particle life time gradient

David Catuhe 7 gadi atpakaļ
vecāks
revīzija
925d1db9ce

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 18551 - 18509
Playground/babylon.d.txt


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 13846 - 13823
dist/preview release/babylon.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 54 - 54
dist/preview release/babylon.js


+ 120 - 58
dist/preview release/babylon.max.js

@@ -55241,9 +55241,9 @@ var BABYLON;
          * Defines how the sprite cell index is updated for the particle
          */
         Particle.prototype.updateCellIndex = function () {
-            var dist = (this.particleSystem.endSpriteCellID - this.particleSystem.startSpriteCellID);
+            var dist = (this._initialEndSpriteCellID - this._initialStartSpriteCellID);
             var ratio = BABYLON.Scalar.Clamp(((this.age * this.particleSystem.spriteCellChangeSpeed) / this.lifeTime) % this.lifeTime);
-            this.cellIndex = this.particleSystem.startSpriteCellID + (ratio * dist) | 0;
+            this.cellIndex = this._initialStartSpriteCellID + (ratio * dist) | 0;
         };
         /**
          * Copy the properties of particle to another one.
@@ -55283,6 +55283,10 @@ var BABYLON;
                 other._currentSize1 = this._currentSize1;
                 other._currentSize2 = this._currentSize2;
             }
+            if (this.particleSystem.isAnimationSheetEnabled) {
+                other._initialStartSpriteCellID = this._initialStartSpriteCellID;
+                other._initialEndSpriteCellID = this._initialEndSpriteCellID;
+            }
         };
         return Particle;
     }());
@@ -55612,6 +55616,14 @@ var BABYLON;
         ParticleSystem.prototype.getSizeGradients = function () {
             return this._sizeGradients;
         };
+        /**
+         * Gets the current list of life time gradients.
+         * You must use addLifeTimeGradient and removeLifeTimeGradient to udpate this list
+         * @returns the list of life time gradients
+         */
+        ParticleSystem.prototype.getLifeTimeGradients = function () {
+            return this._lifeTimeGradients;
+        };
         Object.defineProperty(ParticleSystem.prototype, "direction1", {
             /**
              * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
@@ -55746,6 +55758,57 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem.prototype._addFactorGradient = function (factorGradients, gradient, factor, factor2) {
+            var newGradient = new BABYLON.FactorGradient();
+            newGradient.gradient = gradient;
+            newGradient.factor1 = factor;
+            newGradient.factor2 = factor2;
+            factorGradients.push(newGradient);
+            factorGradients.sort(function (a, b) {
+                if (a.gradient < b.gradient) {
+                    return -1;
+                }
+                else if (a.gradient > b.gradient) {
+                    return 1;
+                }
+                return 0;
+            });
+        };
+        ParticleSystem.prototype._removeFactorGradient = function (factorGradients, gradient) {
+            if (!factorGradients) {
+                return;
+            }
+            var index = 0;
+            for (var _i = 0, factorGradients_1 = factorGradients; _i < factorGradients_1.length; _i++) {
+                var factorGradient = factorGradients_1[_i];
+                if (factorGradient.gradient === gradient) {
+                    factorGradients.splice(index, 1);
+                    break;
+                }
+                index++;
+            }
+        };
+        /**
+         * Adds a new life time gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the life time factor to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         */
+        ParticleSystem.prototype.addLifeTimeGradient = function (gradient, factor, factor2) {
+            if (!this._lifeTimeGradients) {
+                this._lifeTimeGradients = [];
+            }
+            this._addFactorGradient(this._lifeTimeGradients, gradient, factor, factor2);
+            return this;
+        };
+        /**
+         * Remove a specific life time gradient
+         * @param gradient defines the gradient to remove
+         */
+        ParticleSystem.prototype.removeLifeTimeGradient = function (gradient) {
+            this._removeFactorGradient(this._lifeTimeGradients, gradient);
+            return this;
+        };
         /**
          * Adds a new size gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -55756,20 +55819,7 @@ var BABYLON;
             if (!this._sizeGradients) {
                 this._sizeGradients = [];
             }
-            var sizeGradient = new BABYLON.FactorGradient();
-            sizeGradient.gradient = gradient;
-            sizeGradient.factor1 = factor;
-            sizeGradient.factor2 = factor2;
-            this._sizeGradients.push(sizeGradient);
-            this._sizeGradients.sort(function (a, b) {
-                if (a.gradient < b.gradient) {
-                    return -1;
-                }
-                else if (a.gradient > b.gradient) {
-                    return 1;
-                }
-                return 0;
-            });
+            this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);
             return this;
         };
         /**
@@ -55777,18 +55827,7 @@ var BABYLON;
          * @param gradient defines the gradient to remove
          */
         ParticleSystem.prototype.removeSizeGradient = function (gradient) {
-            if (!this._sizeGradients) {
-                return this;
-            }
-            var index = 0;
-            for (var _i = 0, _a = this._sizeGradients; _i < _a.length; _i++) {
-                var sizeGradient = _a[_i];
-                if (sizeGradient.gradient === gradient) {
-                    this._sizeGradients.splice(index, 1);
-                    break;
-                }
-                index++;
-            }
+            this._removeFactorGradient(this._sizeGradients, gradient);
             return this;
         };
         /**
@@ -56029,7 +56068,7 @@ var BABYLON;
                 this._rootParticleSystem.activeSubSystems.splice(index, 1);
             }
         };
-        // end of sub system methods
+        // End of sub system methods
         ParticleSystem.prototype._update = function (newParticles) {
             // Update current
             this._alive = this._particles.length > 0;
@@ -56045,24 +56084,24 @@ var BABYLON;
                 worldMatrix = BABYLON.Matrix.Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);
             }
             var particle;
-            for (var index = 0; index < newParticles; index++) {
-                if (this._particles.length === this._capacity) {
-                    break;
+            var _loop_1 = function () {
+                if (this_1._particles.length === this_1._capacity) {
+                    return "break";
                 }
-                particle = this._createParticle();
-                this._particles.push(particle);
-                var emitPower = BABYLON.Scalar.RandomRange(this.minEmitPower, this.maxEmitPower);
-                if (this.startPositionFunction) {
-                    this.startPositionFunction(worldMatrix, particle.position, particle);
+                particle = this_1._createParticle();
+                this_1._particles.push(particle);
+                var emitPower = BABYLON.Scalar.RandomRange(this_1.minEmitPower, this_1.maxEmitPower);
+                if (this_1.startPositionFunction) {
+                    this_1.startPositionFunction(worldMatrix, particle.position, particle);
                 }
                 else {
-                    this.particleEmitterType.startPositionFunction(worldMatrix, particle.position, particle);
+                    this_1.particleEmitterType.startPositionFunction(worldMatrix, particle.position, particle);
                 }
-                if (this.startDirectionFunction) {
-                    this.startDirectionFunction(worldMatrix, particle.direction, particle);
+                if (this_1.startDirectionFunction) {
+                    this_1.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
                 else {
-                    this.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
+                    this_1.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
                 if (emitPower === 0) {
                     if (!particle._initialDirection) {
@@ -56076,42 +56115,65 @@ var BABYLON;
                     particle._initialDirection = null;
                 }
                 particle.direction.scaleInPlace(emitPower);
-                particle.lifeTime = BABYLON.Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
-                if (!this._sizeGradients || this._sizeGradients.length === 0) {
-                    particle.size = BABYLON.Scalar.RandomRange(this.minSize, this.maxSize);
+                if (this_1.targetStopDuration && this_1._lifeTimeGradients && this_1._lifeTimeGradients.length > 0) {
+                    var ratio_1 = BABYLON.Scalar.Clamp(this_1._actualFrame / this_1.targetStopDuration);
+                    BABYLON.Tools.GetCurrentGradient(ratio_1, this_1._lifeTimeGradients, function (currentGradient, nextGradient, scale) {
+                        var factorGradient1 = currentGradient;
+                        var factorGradient2 = nextGradient;
+                        var lifeTime1 = factorGradient1.getFactor();
+                        var lifeTime2 = factorGradient2.getFactor();
+                        var gradient = (ratio_1 - factorGradient1.gradient) / (factorGradient2.gradient - factorGradient1.gradient);
+                        particle.lifeTime = BABYLON.Scalar.Lerp(lifeTime1, lifeTime2, gradient);
+                    });
+                }
+                else {
+                    particle.lifeTime = BABYLON.Scalar.RandomRange(this_1.minLifeTime, this_1.maxLifeTime);
+                }
+                if (!this_1._sizeGradients || this_1._sizeGradients.length === 0) {
+                    particle.size = BABYLON.Scalar.RandomRange(this_1.minSize, this_1.maxSize);
                 }
                 else {
-                    particle._currentSizeGradient = this._sizeGradients[0];
+                    particle._currentSizeGradient = this_1._sizeGradients[0];
                     particle._currentSize1 = particle._currentSizeGradient.getFactor();
                     particle.size = particle._currentSize1;
-                    if (this._sizeGradients.length > 1) {
-                        particle._currentSize2 = this._sizeGradients[1].getFactor();
+                    if (this_1._sizeGradients.length > 1) {
+                        particle._currentSize2 = this_1._sizeGradients[1].getFactor();
                     }
                     else {
                         particle._currentSize2 = particle._currentSize1;
                     }
                 }
                 particle._initialSize = particle.size;
-                particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this.minScaleX, this.maxScaleX), BABYLON.Scalar.RandomRange(this.minScaleY, this.maxScaleY));
-                particle.angularSpeed = BABYLON.Scalar.RandomRange(this.minAngularSpeed, this.maxAngularSpeed);
-                particle.angle = BABYLON.Scalar.RandomRange(this.minInitialRotation, this.maxInitialRotation);
-                if (!this._colorGradients || this._colorGradients.length === 0) {
-                    var step = BABYLON.Scalar.RandomRange(0, 1.0);
-                    BABYLON.Color4.LerpToRef(this.color1, this.color2, step, particle.color);
-                    this.colorDead.subtractToRef(particle.color, this._colorDiff);
-                    this._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
+                particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this_1.minScaleX, this_1.maxScaleX), BABYLON.Scalar.RandomRange(this_1.minScaleY, this_1.maxScaleY));
+                particle.angularSpeed = BABYLON.Scalar.RandomRange(this_1.minAngularSpeed, this_1.maxAngularSpeed);
+                particle.angle = BABYLON.Scalar.RandomRange(this_1.minInitialRotation, this_1.maxInitialRotation);
+                if (!this_1._colorGradients || this_1._colorGradients.length === 0) {
+                    step = BABYLON.Scalar.RandomRange(0, 1.0);
+                    BABYLON.Color4.LerpToRef(this_1.color1, this_1.color2, step, particle.color);
+                    this_1.colorDead.subtractToRef(particle.color, this_1._colorDiff);
+                    this_1._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
                 }
                 else {
-                    particle._currentColorGradient = this._colorGradients[0];
+                    particle._currentColorGradient = this_1._colorGradients[0];
                     particle._currentColorGradient.getColorToRef(particle.color);
                     particle._currentColor1.copyFrom(particle.color);
-                    if (this._colorGradients.length > 1) {
-                        this._colorGradients[1].getColorToRef(particle._currentColor2);
+                    if (this_1._colorGradients.length > 1) {
+                        this_1._colorGradients[1].getColorToRef(particle._currentColor2);
                     }
                     else {
                         particle._currentColor2.copyFrom(particle.color);
                     }
                 }
+                if (this_1._isAnimationSheetEnabled) {
+                    particle._initialStartSpriteCellID = this_1.startSpriteCellID;
+                    particle._initialEndSpriteCellID = this_1.endSpriteCellID;
+                }
+            };
+            var this_1 = this, step;
+            for (var index = 0; index < newParticles; index++) {
+                var state_1 = _loop_1();
+                if (state_1 === "break")
+                    break;
             }
         };
         /** @hidden */

+ 120 - 58
dist/preview release/babylon.no-module.max.js

@@ -55208,9 +55208,9 @@ var BABYLON;
          * Defines how the sprite cell index is updated for the particle
          */
         Particle.prototype.updateCellIndex = function () {
-            var dist = (this.particleSystem.endSpriteCellID - this.particleSystem.startSpriteCellID);
+            var dist = (this._initialEndSpriteCellID - this._initialStartSpriteCellID);
             var ratio = BABYLON.Scalar.Clamp(((this.age * this.particleSystem.spriteCellChangeSpeed) / this.lifeTime) % this.lifeTime);
-            this.cellIndex = this.particleSystem.startSpriteCellID + (ratio * dist) | 0;
+            this.cellIndex = this._initialStartSpriteCellID + (ratio * dist) | 0;
         };
         /**
          * Copy the properties of particle to another one.
@@ -55250,6 +55250,10 @@ var BABYLON;
                 other._currentSize1 = this._currentSize1;
                 other._currentSize2 = this._currentSize2;
             }
+            if (this.particleSystem.isAnimationSheetEnabled) {
+                other._initialStartSpriteCellID = this._initialStartSpriteCellID;
+                other._initialEndSpriteCellID = this._initialEndSpriteCellID;
+            }
         };
         return Particle;
     }());
@@ -55579,6 +55583,14 @@ var BABYLON;
         ParticleSystem.prototype.getSizeGradients = function () {
             return this._sizeGradients;
         };
+        /**
+         * Gets the current list of life time gradients.
+         * You must use addLifeTimeGradient and removeLifeTimeGradient to udpate this list
+         * @returns the list of life time gradients
+         */
+        ParticleSystem.prototype.getLifeTimeGradients = function () {
+            return this._lifeTimeGradients;
+        };
         Object.defineProperty(ParticleSystem.prototype, "direction1", {
             /**
              * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
@@ -55713,6 +55725,57 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem.prototype._addFactorGradient = function (factorGradients, gradient, factor, factor2) {
+            var newGradient = new BABYLON.FactorGradient();
+            newGradient.gradient = gradient;
+            newGradient.factor1 = factor;
+            newGradient.factor2 = factor2;
+            factorGradients.push(newGradient);
+            factorGradients.sort(function (a, b) {
+                if (a.gradient < b.gradient) {
+                    return -1;
+                }
+                else if (a.gradient > b.gradient) {
+                    return 1;
+                }
+                return 0;
+            });
+        };
+        ParticleSystem.prototype._removeFactorGradient = function (factorGradients, gradient) {
+            if (!factorGradients) {
+                return;
+            }
+            var index = 0;
+            for (var _i = 0, factorGradients_1 = factorGradients; _i < factorGradients_1.length; _i++) {
+                var factorGradient = factorGradients_1[_i];
+                if (factorGradient.gradient === gradient) {
+                    factorGradients.splice(index, 1);
+                    break;
+                }
+                index++;
+            }
+        };
+        /**
+         * Adds a new life time gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the life time factor to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         */
+        ParticleSystem.prototype.addLifeTimeGradient = function (gradient, factor, factor2) {
+            if (!this._lifeTimeGradients) {
+                this._lifeTimeGradients = [];
+            }
+            this._addFactorGradient(this._lifeTimeGradients, gradient, factor, factor2);
+            return this;
+        };
+        /**
+         * Remove a specific life time gradient
+         * @param gradient defines the gradient to remove
+         */
+        ParticleSystem.prototype.removeLifeTimeGradient = function (gradient) {
+            this._removeFactorGradient(this._lifeTimeGradients, gradient);
+            return this;
+        };
         /**
          * Adds a new size gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -55723,20 +55786,7 @@ var BABYLON;
             if (!this._sizeGradients) {
                 this._sizeGradients = [];
             }
-            var sizeGradient = new BABYLON.FactorGradient();
-            sizeGradient.gradient = gradient;
-            sizeGradient.factor1 = factor;
-            sizeGradient.factor2 = factor2;
-            this._sizeGradients.push(sizeGradient);
-            this._sizeGradients.sort(function (a, b) {
-                if (a.gradient < b.gradient) {
-                    return -1;
-                }
-                else if (a.gradient > b.gradient) {
-                    return 1;
-                }
-                return 0;
-            });
+            this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);
             return this;
         };
         /**
@@ -55744,18 +55794,7 @@ var BABYLON;
          * @param gradient defines the gradient to remove
          */
         ParticleSystem.prototype.removeSizeGradient = function (gradient) {
-            if (!this._sizeGradients) {
-                return this;
-            }
-            var index = 0;
-            for (var _i = 0, _a = this._sizeGradients; _i < _a.length; _i++) {
-                var sizeGradient = _a[_i];
-                if (sizeGradient.gradient === gradient) {
-                    this._sizeGradients.splice(index, 1);
-                    break;
-                }
-                index++;
-            }
+            this._removeFactorGradient(this._sizeGradients, gradient);
             return this;
         };
         /**
@@ -55996,7 +56035,7 @@ var BABYLON;
                 this._rootParticleSystem.activeSubSystems.splice(index, 1);
             }
         };
-        // end of sub system methods
+        // End of sub system methods
         ParticleSystem.prototype._update = function (newParticles) {
             // Update current
             this._alive = this._particles.length > 0;
@@ -56012,24 +56051,24 @@ var BABYLON;
                 worldMatrix = BABYLON.Matrix.Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);
             }
             var particle;
-            for (var index = 0; index < newParticles; index++) {
-                if (this._particles.length === this._capacity) {
-                    break;
+            var _loop_1 = function () {
+                if (this_1._particles.length === this_1._capacity) {
+                    return "break";
                 }
-                particle = this._createParticle();
-                this._particles.push(particle);
-                var emitPower = BABYLON.Scalar.RandomRange(this.minEmitPower, this.maxEmitPower);
-                if (this.startPositionFunction) {
-                    this.startPositionFunction(worldMatrix, particle.position, particle);
+                particle = this_1._createParticle();
+                this_1._particles.push(particle);
+                var emitPower = BABYLON.Scalar.RandomRange(this_1.minEmitPower, this_1.maxEmitPower);
+                if (this_1.startPositionFunction) {
+                    this_1.startPositionFunction(worldMatrix, particle.position, particle);
                 }
                 else {
-                    this.particleEmitterType.startPositionFunction(worldMatrix, particle.position, particle);
+                    this_1.particleEmitterType.startPositionFunction(worldMatrix, particle.position, particle);
                 }
-                if (this.startDirectionFunction) {
-                    this.startDirectionFunction(worldMatrix, particle.direction, particle);
+                if (this_1.startDirectionFunction) {
+                    this_1.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
                 else {
-                    this.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
+                    this_1.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
                 if (emitPower === 0) {
                     if (!particle._initialDirection) {
@@ -56043,42 +56082,65 @@ var BABYLON;
                     particle._initialDirection = null;
                 }
                 particle.direction.scaleInPlace(emitPower);
-                particle.lifeTime = BABYLON.Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
-                if (!this._sizeGradients || this._sizeGradients.length === 0) {
-                    particle.size = BABYLON.Scalar.RandomRange(this.minSize, this.maxSize);
+                if (this_1.targetStopDuration && this_1._lifeTimeGradients && this_1._lifeTimeGradients.length > 0) {
+                    var ratio_1 = BABYLON.Scalar.Clamp(this_1._actualFrame / this_1.targetStopDuration);
+                    BABYLON.Tools.GetCurrentGradient(ratio_1, this_1._lifeTimeGradients, function (currentGradient, nextGradient, scale) {
+                        var factorGradient1 = currentGradient;
+                        var factorGradient2 = nextGradient;
+                        var lifeTime1 = factorGradient1.getFactor();
+                        var lifeTime2 = factorGradient2.getFactor();
+                        var gradient = (ratio_1 - factorGradient1.gradient) / (factorGradient2.gradient - factorGradient1.gradient);
+                        particle.lifeTime = BABYLON.Scalar.Lerp(lifeTime1, lifeTime2, gradient);
+                    });
+                }
+                else {
+                    particle.lifeTime = BABYLON.Scalar.RandomRange(this_1.minLifeTime, this_1.maxLifeTime);
+                }
+                if (!this_1._sizeGradients || this_1._sizeGradients.length === 0) {
+                    particle.size = BABYLON.Scalar.RandomRange(this_1.minSize, this_1.maxSize);
                 }
                 else {
-                    particle._currentSizeGradient = this._sizeGradients[0];
+                    particle._currentSizeGradient = this_1._sizeGradients[0];
                     particle._currentSize1 = particle._currentSizeGradient.getFactor();
                     particle.size = particle._currentSize1;
-                    if (this._sizeGradients.length > 1) {
-                        particle._currentSize2 = this._sizeGradients[1].getFactor();
+                    if (this_1._sizeGradients.length > 1) {
+                        particle._currentSize2 = this_1._sizeGradients[1].getFactor();
                     }
                     else {
                         particle._currentSize2 = particle._currentSize1;
                     }
                 }
                 particle._initialSize = particle.size;
-                particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this.minScaleX, this.maxScaleX), BABYLON.Scalar.RandomRange(this.minScaleY, this.maxScaleY));
-                particle.angularSpeed = BABYLON.Scalar.RandomRange(this.minAngularSpeed, this.maxAngularSpeed);
-                particle.angle = BABYLON.Scalar.RandomRange(this.minInitialRotation, this.maxInitialRotation);
-                if (!this._colorGradients || this._colorGradients.length === 0) {
-                    var step = BABYLON.Scalar.RandomRange(0, 1.0);
-                    BABYLON.Color4.LerpToRef(this.color1, this.color2, step, particle.color);
-                    this.colorDead.subtractToRef(particle.color, this._colorDiff);
-                    this._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
+                particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this_1.minScaleX, this_1.maxScaleX), BABYLON.Scalar.RandomRange(this_1.minScaleY, this_1.maxScaleY));
+                particle.angularSpeed = BABYLON.Scalar.RandomRange(this_1.minAngularSpeed, this_1.maxAngularSpeed);
+                particle.angle = BABYLON.Scalar.RandomRange(this_1.minInitialRotation, this_1.maxInitialRotation);
+                if (!this_1._colorGradients || this_1._colorGradients.length === 0) {
+                    step = BABYLON.Scalar.RandomRange(0, 1.0);
+                    BABYLON.Color4.LerpToRef(this_1.color1, this_1.color2, step, particle.color);
+                    this_1.colorDead.subtractToRef(particle.color, this_1._colorDiff);
+                    this_1._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
                 }
                 else {
-                    particle._currentColorGradient = this._colorGradients[0];
+                    particle._currentColorGradient = this_1._colorGradients[0];
                     particle._currentColorGradient.getColorToRef(particle.color);
                     particle._currentColor1.copyFrom(particle.color);
-                    if (this._colorGradients.length > 1) {
-                        this._colorGradients[1].getColorToRef(particle._currentColor2);
+                    if (this_1._colorGradients.length > 1) {
+                        this_1._colorGradients[1].getColorToRef(particle._currentColor2);
                     }
                     else {
                         particle._currentColor2.copyFrom(particle.color);
                     }
                 }
+                if (this_1._isAnimationSheetEnabled) {
+                    particle._initialStartSpriteCellID = this_1.startSpriteCellID;
+                    particle._initialEndSpriteCellID = this_1.endSpriteCellID;
+                }
+            };
+            var this_1 = this, step;
+            for (var index = 0; index < newParticles; index++) {
+                var state_1 = _loop_1();
+                if (state_1 === "break")
+                    break;
             }
         };
         /** @hidden */

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 25 - 25
dist/preview release/babylon.worker.js


+ 120 - 58
dist/preview release/es6.js

@@ -55208,9 +55208,9 @@ var BABYLON;
          * Defines how the sprite cell index is updated for the particle
          */
         Particle.prototype.updateCellIndex = function () {
-            var dist = (this.particleSystem.endSpriteCellID - this.particleSystem.startSpriteCellID);
+            var dist = (this._initialEndSpriteCellID - this._initialStartSpriteCellID);
             var ratio = BABYLON.Scalar.Clamp(((this.age * this.particleSystem.spriteCellChangeSpeed) / this.lifeTime) % this.lifeTime);
-            this.cellIndex = this.particleSystem.startSpriteCellID + (ratio * dist) | 0;
+            this.cellIndex = this._initialStartSpriteCellID + (ratio * dist) | 0;
         };
         /**
          * Copy the properties of particle to another one.
@@ -55250,6 +55250,10 @@ var BABYLON;
                 other._currentSize1 = this._currentSize1;
                 other._currentSize2 = this._currentSize2;
             }
+            if (this.particleSystem.isAnimationSheetEnabled) {
+                other._initialStartSpriteCellID = this._initialStartSpriteCellID;
+                other._initialEndSpriteCellID = this._initialEndSpriteCellID;
+            }
         };
         return Particle;
     }());
@@ -55579,6 +55583,14 @@ var BABYLON;
         ParticleSystem.prototype.getSizeGradients = function () {
             return this._sizeGradients;
         };
+        /**
+         * Gets the current list of life time gradients.
+         * You must use addLifeTimeGradient and removeLifeTimeGradient to udpate this list
+         * @returns the list of life time gradients
+         */
+        ParticleSystem.prototype.getLifeTimeGradients = function () {
+            return this._lifeTimeGradients;
+        };
         Object.defineProperty(ParticleSystem.prototype, "direction1", {
             /**
              * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
@@ -55713,6 +55725,57 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem.prototype._addFactorGradient = function (factorGradients, gradient, factor, factor2) {
+            var newGradient = new BABYLON.FactorGradient();
+            newGradient.gradient = gradient;
+            newGradient.factor1 = factor;
+            newGradient.factor2 = factor2;
+            factorGradients.push(newGradient);
+            factorGradients.sort(function (a, b) {
+                if (a.gradient < b.gradient) {
+                    return -1;
+                }
+                else if (a.gradient > b.gradient) {
+                    return 1;
+                }
+                return 0;
+            });
+        };
+        ParticleSystem.prototype._removeFactorGradient = function (factorGradients, gradient) {
+            if (!factorGradients) {
+                return;
+            }
+            var index = 0;
+            for (var _i = 0, factorGradients_1 = factorGradients; _i < factorGradients_1.length; _i++) {
+                var factorGradient = factorGradients_1[_i];
+                if (factorGradient.gradient === gradient) {
+                    factorGradients.splice(index, 1);
+                    break;
+                }
+                index++;
+            }
+        };
+        /**
+         * Adds a new life time gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the life time factor to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         */
+        ParticleSystem.prototype.addLifeTimeGradient = function (gradient, factor, factor2) {
+            if (!this._lifeTimeGradients) {
+                this._lifeTimeGradients = [];
+            }
+            this._addFactorGradient(this._lifeTimeGradients, gradient, factor, factor2);
+            return this;
+        };
+        /**
+         * Remove a specific life time gradient
+         * @param gradient defines the gradient to remove
+         */
+        ParticleSystem.prototype.removeLifeTimeGradient = function (gradient) {
+            this._removeFactorGradient(this._lifeTimeGradients, gradient);
+            return this;
+        };
         /**
          * Adds a new size gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -55723,20 +55786,7 @@ var BABYLON;
             if (!this._sizeGradients) {
                 this._sizeGradients = [];
             }
-            var sizeGradient = new BABYLON.FactorGradient();
-            sizeGradient.gradient = gradient;
-            sizeGradient.factor1 = factor;
-            sizeGradient.factor2 = factor2;
-            this._sizeGradients.push(sizeGradient);
-            this._sizeGradients.sort(function (a, b) {
-                if (a.gradient < b.gradient) {
-                    return -1;
-                }
-                else if (a.gradient > b.gradient) {
-                    return 1;
-                }
-                return 0;
-            });
+            this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);
             return this;
         };
         /**
@@ -55744,18 +55794,7 @@ var BABYLON;
          * @param gradient defines the gradient to remove
          */
         ParticleSystem.prototype.removeSizeGradient = function (gradient) {
-            if (!this._sizeGradients) {
-                return this;
-            }
-            var index = 0;
-            for (var _i = 0, _a = this._sizeGradients; _i < _a.length; _i++) {
-                var sizeGradient = _a[_i];
-                if (sizeGradient.gradient === gradient) {
-                    this._sizeGradients.splice(index, 1);
-                    break;
-                }
-                index++;
-            }
+            this._removeFactorGradient(this._sizeGradients, gradient);
             return this;
         };
         /**
@@ -55996,7 +56035,7 @@ var BABYLON;
                 this._rootParticleSystem.activeSubSystems.splice(index, 1);
             }
         };
-        // end of sub system methods
+        // End of sub system methods
         ParticleSystem.prototype._update = function (newParticles) {
             // Update current
             this._alive = this._particles.length > 0;
@@ -56012,24 +56051,24 @@ var BABYLON;
                 worldMatrix = BABYLON.Matrix.Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);
             }
             var particle;
-            for (var index = 0; index < newParticles; index++) {
-                if (this._particles.length === this._capacity) {
-                    break;
+            var _loop_1 = function () {
+                if (this_1._particles.length === this_1._capacity) {
+                    return "break";
                 }
-                particle = this._createParticle();
-                this._particles.push(particle);
-                var emitPower = BABYLON.Scalar.RandomRange(this.minEmitPower, this.maxEmitPower);
-                if (this.startPositionFunction) {
-                    this.startPositionFunction(worldMatrix, particle.position, particle);
+                particle = this_1._createParticle();
+                this_1._particles.push(particle);
+                var emitPower = BABYLON.Scalar.RandomRange(this_1.minEmitPower, this_1.maxEmitPower);
+                if (this_1.startPositionFunction) {
+                    this_1.startPositionFunction(worldMatrix, particle.position, particle);
                 }
                 else {
-                    this.particleEmitterType.startPositionFunction(worldMatrix, particle.position, particle);
+                    this_1.particleEmitterType.startPositionFunction(worldMatrix, particle.position, particle);
                 }
-                if (this.startDirectionFunction) {
-                    this.startDirectionFunction(worldMatrix, particle.direction, particle);
+                if (this_1.startDirectionFunction) {
+                    this_1.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
                 else {
-                    this.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
+                    this_1.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
                 if (emitPower === 0) {
                     if (!particle._initialDirection) {
@@ -56043,42 +56082,65 @@ var BABYLON;
                     particle._initialDirection = null;
                 }
                 particle.direction.scaleInPlace(emitPower);
-                particle.lifeTime = BABYLON.Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
-                if (!this._sizeGradients || this._sizeGradients.length === 0) {
-                    particle.size = BABYLON.Scalar.RandomRange(this.minSize, this.maxSize);
+                if (this_1.targetStopDuration && this_1._lifeTimeGradients && this_1._lifeTimeGradients.length > 0) {
+                    var ratio_1 = BABYLON.Scalar.Clamp(this_1._actualFrame / this_1.targetStopDuration);
+                    BABYLON.Tools.GetCurrentGradient(ratio_1, this_1._lifeTimeGradients, function (currentGradient, nextGradient, scale) {
+                        var factorGradient1 = currentGradient;
+                        var factorGradient2 = nextGradient;
+                        var lifeTime1 = factorGradient1.getFactor();
+                        var lifeTime2 = factorGradient2.getFactor();
+                        var gradient = (ratio_1 - factorGradient1.gradient) / (factorGradient2.gradient - factorGradient1.gradient);
+                        particle.lifeTime = BABYLON.Scalar.Lerp(lifeTime1, lifeTime2, gradient);
+                    });
+                }
+                else {
+                    particle.lifeTime = BABYLON.Scalar.RandomRange(this_1.minLifeTime, this_1.maxLifeTime);
+                }
+                if (!this_1._sizeGradients || this_1._sizeGradients.length === 0) {
+                    particle.size = BABYLON.Scalar.RandomRange(this_1.minSize, this_1.maxSize);
                 }
                 else {
-                    particle._currentSizeGradient = this._sizeGradients[0];
+                    particle._currentSizeGradient = this_1._sizeGradients[0];
                     particle._currentSize1 = particle._currentSizeGradient.getFactor();
                     particle.size = particle._currentSize1;
-                    if (this._sizeGradients.length > 1) {
-                        particle._currentSize2 = this._sizeGradients[1].getFactor();
+                    if (this_1._sizeGradients.length > 1) {
+                        particle._currentSize2 = this_1._sizeGradients[1].getFactor();
                     }
                     else {
                         particle._currentSize2 = particle._currentSize1;
                     }
                 }
                 particle._initialSize = particle.size;
-                particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this.minScaleX, this.maxScaleX), BABYLON.Scalar.RandomRange(this.minScaleY, this.maxScaleY));
-                particle.angularSpeed = BABYLON.Scalar.RandomRange(this.minAngularSpeed, this.maxAngularSpeed);
-                particle.angle = BABYLON.Scalar.RandomRange(this.minInitialRotation, this.maxInitialRotation);
-                if (!this._colorGradients || this._colorGradients.length === 0) {
-                    var step = BABYLON.Scalar.RandomRange(0, 1.0);
-                    BABYLON.Color4.LerpToRef(this.color1, this.color2, step, particle.color);
-                    this.colorDead.subtractToRef(particle.color, this._colorDiff);
-                    this._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
+                particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this_1.minScaleX, this_1.maxScaleX), BABYLON.Scalar.RandomRange(this_1.minScaleY, this_1.maxScaleY));
+                particle.angularSpeed = BABYLON.Scalar.RandomRange(this_1.minAngularSpeed, this_1.maxAngularSpeed);
+                particle.angle = BABYLON.Scalar.RandomRange(this_1.minInitialRotation, this_1.maxInitialRotation);
+                if (!this_1._colorGradients || this_1._colorGradients.length === 0) {
+                    step = BABYLON.Scalar.RandomRange(0, 1.0);
+                    BABYLON.Color4.LerpToRef(this_1.color1, this_1.color2, step, particle.color);
+                    this_1.colorDead.subtractToRef(particle.color, this_1._colorDiff);
+                    this_1._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
                 }
                 else {
-                    particle._currentColorGradient = this._colorGradients[0];
+                    particle._currentColorGradient = this_1._colorGradients[0];
                     particle._currentColorGradient.getColorToRef(particle.color);
                     particle._currentColor1.copyFrom(particle.color);
-                    if (this._colorGradients.length > 1) {
-                        this._colorGradients[1].getColorToRef(particle._currentColor2);
+                    if (this_1._colorGradients.length > 1) {
+                        this_1._colorGradients[1].getColorToRef(particle._currentColor2);
                     }
                     else {
                         particle._currentColor2.copyFrom(particle.color);
                     }
                 }
+                if (this_1._isAnimationSheetEnabled) {
+                    particle._initialStartSpriteCellID = this_1.startSpriteCellID;
+                    particle._initialEndSpriteCellID = this_1.endSpriteCellID;
+                }
+            };
+            var this_1 = this, step;
+            for (var index = 0; index < newParticles; index++) {
+                var state_1 = _loop_1();
+                if (state_1 === "break")
+                    break;
             }
         };
         /** @hidden */

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 45 - 45
dist/preview release/viewer/babylon.viewer.js


+ 120 - 58
dist/preview release/viewer/babylon.viewer.max.js

@@ -55329,9 +55329,9 @@ var BABYLON;
          * Defines how the sprite cell index is updated for the particle
          */
         Particle.prototype.updateCellIndex = function () {
-            var dist = (this.particleSystem.endSpriteCellID - this.particleSystem.startSpriteCellID);
+            var dist = (this._initialEndSpriteCellID - this._initialStartSpriteCellID);
             var ratio = BABYLON.Scalar.Clamp(((this.age * this.particleSystem.spriteCellChangeSpeed) / this.lifeTime) % this.lifeTime);
-            this.cellIndex = this.particleSystem.startSpriteCellID + (ratio * dist) | 0;
+            this.cellIndex = this._initialStartSpriteCellID + (ratio * dist) | 0;
         };
         /**
          * Copy the properties of particle to another one.
@@ -55371,6 +55371,10 @@ var BABYLON;
                 other._currentSize1 = this._currentSize1;
                 other._currentSize2 = this._currentSize2;
             }
+            if (this.particleSystem.isAnimationSheetEnabled) {
+                other._initialStartSpriteCellID = this._initialStartSpriteCellID;
+                other._initialEndSpriteCellID = this._initialEndSpriteCellID;
+            }
         };
         return Particle;
     }());
@@ -55700,6 +55704,14 @@ var BABYLON;
         ParticleSystem.prototype.getSizeGradients = function () {
             return this._sizeGradients;
         };
+        /**
+         * Gets the current list of life time gradients.
+         * You must use addLifeTimeGradient and removeLifeTimeGradient to udpate this list
+         * @returns the list of life time gradients
+         */
+        ParticleSystem.prototype.getLifeTimeGradients = function () {
+            return this._lifeTimeGradients;
+        };
         Object.defineProperty(ParticleSystem.prototype, "direction1", {
             /**
              * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
@@ -55834,6 +55846,57 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem.prototype._addFactorGradient = function (factorGradients, gradient, factor, factor2) {
+            var newGradient = new BABYLON.FactorGradient();
+            newGradient.gradient = gradient;
+            newGradient.factor1 = factor;
+            newGradient.factor2 = factor2;
+            factorGradients.push(newGradient);
+            factorGradients.sort(function (a, b) {
+                if (a.gradient < b.gradient) {
+                    return -1;
+                }
+                else if (a.gradient > b.gradient) {
+                    return 1;
+                }
+                return 0;
+            });
+        };
+        ParticleSystem.prototype._removeFactorGradient = function (factorGradients, gradient) {
+            if (!factorGradients) {
+                return;
+            }
+            var index = 0;
+            for (var _i = 0, factorGradients_1 = factorGradients; _i < factorGradients_1.length; _i++) {
+                var factorGradient = factorGradients_1[_i];
+                if (factorGradient.gradient === gradient) {
+                    factorGradients.splice(index, 1);
+                    break;
+                }
+                index++;
+            }
+        };
+        /**
+         * Adds a new life time gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the life time factor to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         */
+        ParticleSystem.prototype.addLifeTimeGradient = function (gradient, factor, factor2) {
+            if (!this._lifeTimeGradients) {
+                this._lifeTimeGradients = [];
+            }
+            this._addFactorGradient(this._lifeTimeGradients, gradient, factor, factor2);
+            return this;
+        };
+        /**
+         * Remove a specific life time gradient
+         * @param gradient defines the gradient to remove
+         */
+        ParticleSystem.prototype.removeLifeTimeGradient = function (gradient) {
+            this._removeFactorGradient(this._lifeTimeGradients, gradient);
+            return this;
+        };
         /**
          * Adds a new size gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -55844,20 +55907,7 @@ var BABYLON;
             if (!this._sizeGradients) {
                 this._sizeGradients = [];
             }
-            var sizeGradient = new BABYLON.FactorGradient();
-            sizeGradient.gradient = gradient;
-            sizeGradient.factor1 = factor;
-            sizeGradient.factor2 = factor2;
-            this._sizeGradients.push(sizeGradient);
-            this._sizeGradients.sort(function (a, b) {
-                if (a.gradient < b.gradient) {
-                    return -1;
-                }
-                else if (a.gradient > b.gradient) {
-                    return 1;
-                }
-                return 0;
-            });
+            this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);
             return this;
         };
         /**
@@ -55865,18 +55915,7 @@ var BABYLON;
          * @param gradient defines the gradient to remove
          */
         ParticleSystem.prototype.removeSizeGradient = function (gradient) {
-            if (!this._sizeGradients) {
-                return this;
-            }
-            var index = 0;
-            for (var _i = 0, _a = this._sizeGradients; _i < _a.length; _i++) {
-                var sizeGradient = _a[_i];
-                if (sizeGradient.gradient === gradient) {
-                    this._sizeGradients.splice(index, 1);
-                    break;
-                }
-                index++;
-            }
+            this._removeFactorGradient(this._sizeGradients, gradient);
             return this;
         };
         /**
@@ -56117,7 +56156,7 @@ var BABYLON;
                 this._rootParticleSystem.activeSubSystems.splice(index, 1);
             }
         };
-        // end of sub system methods
+        // End of sub system methods
         ParticleSystem.prototype._update = function (newParticles) {
             // Update current
             this._alive = this._particles.length > 0;
@@ -56133,24 +56172,24 @@ var BABYLON;
                 worldMatrix = BABYLON.Matrix.Translation(emitterPosition.x, emitterPosition.y, emitterPosition.z);
             }
             var particle;
-            for (var index = 0; index < newParticles; index++) {
-                if (this._particles.length === this._capacity) {
-                    break;
+            var _loop_1 = function () {
+                if (this_1._particles.length === this_1._capacity) {
+                    return "break";
                 }
-                particle = this._createParticle();
-                this._particles.push(particle);
-                var emitPower = BABYLON.Scalar.RandomRange(this.minEmitPower, this.maxEmitPower);
-                if (this.startPositionFunction) {
-                    this.startPositionFunction(worldMatrix, particle.position, particle);
+                particle = this_1._createParticle();
+                this_1._particles.push(particle);
+                var emitPower = BABYLON.Scalar.RandomRange(this_1.minEmitPower, this_1.maxEmitPower);
+                if (this_1.startPositionFunction) {
+                    this_1.startPositionFunction(worldMatrix, particle.position, particle);
                 }
                 else {
-                    this.particleEmitterType.startPositionFunction(worldMatrix, particle.position, particle);
+                    this_1.particleEmitterType.startPositionFunction(worldMatrix, particle.position, particle);
                 }
-                if (this.startDirectionFunction) {
-                    this.startDirectionFunction(worldMatrix, particle.direction, particle);
+                if (this_1.startDirectionFunction) {
+                    this_1.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
                 else {
-                    this.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
+                    this_1.particleEmitterType.startDirectionFunction(worldMatrix, particle.direction, particle);
                 }
                 if (emitPower === 0) {
                     if (!particle._initialDirection) {
@@ -56164,42 +56203,65 @@ var BABYLON;
                     particle._initialDirection = null;
                 }
                 particle.direction.scaleInPlace(emitPower);
-                particle.lifeTime = BABYLON.Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
-                if (!this._sizeGradients || this._sizeGradients.length === 0) {
-                    particle.size = BABYLON.Scalar.RandomRange(this.minSize, this.maxSize);
+                if (this_1.targetStopDuration && this_1._lifeTimeGradients && this_1._lifeTimeGradients.length > 0) {
+                    var ratio_1 = BABYLON.Scalar.Clamp(this_1._actualFrame / this_1.targetStopDuration);
+                    BABYLON.Tools.GetCurrentGradient(ratio_1, this_1._lifeTimeGradients, function (currentGradient, nextGradient, scale) {
+                        var factorGradient1 = currentGradient;
+                        var factorGradient2 = nextGradient;
+                        var lifeTime1 = factorGradient1.getFactor();
+                        var lifeTime2 = factorGradient2.getFactor();
+                        var gradient = (ratio_1 - factorGradient1.gradient) / (factorGradient2.gradient - factorGradient1.gradient);
+                        particle.lifeTime = BABYLON.Scalar.Lerp(lifeTime1, lifeTime2, gradient);
+                    });
+                }
+                else {
+                    particle.lifeTime = BABYLON.Scalar.RandomRange(this_1.minLifeTime, this_1.maxLifeTime);
+                }
+                if (!this_1._sizeGradients || this_1._sizeGradients.length === 0) {
+                    particle.size = BABYLON.Scalar.RandomRange(this_1.minSize, this_1.maxSize);
                 }
                 else {
-                    particle._currentSizeGradient = this._sizeGradients[0];
+                    particle._currentSizeGradient = this_1._sizeGradients[0];
                     particle._currentSize1 = particle._currentSizeGradient.getFactor();
                     particle.size = particle._currentSize1;
-                    if (this._sizeGradients.length > 1) {
-                        particle._currentSize2 = this._sizeGradients[1].getFactor();
+                    if (this_1._sizeGradients.length > 1) {
+                        particle._currentSize2 = this_1._sizeGradients[1].getFactor();
                     }
                     else {
                         particle._currentSize2 = particle._currentSize1;
                     }
                 }
                 particle._initialSize = particle.size;
-                particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this.minScaleX, this.maxScaleX), BABYLON.Scalar.RandomRange(this.minScaleY, this.maxScaleY));
-                particle.angularSpeed = BABYLON.Scalar.RandomRange(this.minAngularSpeed, this.maxAngularSpeed);
-                particle.angle = BABYLON.Scalar.RandomRange(this.minInitialRotation, this.maxInitialRotation);
-                if (!this._colorGradients || this._colorGradients.length === 0) {
-                    var step = BABYLON.Scalar.RandomRange(0, 1.0);
-                    BABYLON.Color4.LerpToRef(this.color1, this.color2, step, particle.color);
-                    this.colorDead.subtractToRef(particle.color, this._colorDiff);
-                    this._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
+                particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this_1.minScaleX, this_1.maxScaleX), BABYLON.Scalar.RandomRange(this_1.minScaleY, this_1.maxScaleY));
+                particle.angularSpeed = BABYLON.Scalar.RandomRange(this_1.minAngularSpeed, this_1.maxAngularSpeed);
+                particle.angle = BABYLON.Scalar.RandomRange(this_1.minInitialRotation, this_1.maxInitialRotation);
+                if (!this_1._colorGradients || this_1._colorGradients.length === 0) {
+                    step = BABYLON.Scalar.RandomRange(0, 1.0);
+                    BABYLON.Color4.LerpToRef(this_1.color1, this_1.color2, step, particle.color);
+                    this_1.colorDead.subtractToRef(particle.color, this_1._colorDiff);
+                    this_1._colorDiff.scaleToRef(1.0 / particle.lifeTime, particle.colorStep);
                 }
                 else {
-                    particle._currentColorGradient = this._colorGradients[0];
+                    particle._currentColorGradient = this_1._colorGradients[0];
                     particle._currentColorGradient.getColorToRef(particle.color);
                     particle._currentColor1.copyFrom(particle.color);
-                    if (this._colorGradients.length > 1) {
-                        this._colorGradients[1].getColorToRef(particle._currentColor2);
+                    if (this_1._colorGradients.length > 1) {
+                        this_1._colorGradients[1].getColorToRef(particle._currentColor2);
                     }
                     else {
                         particle._currentColor2.copyFrom(particle.color);
                     }
                 }
+                if (this_1._isAnimationSheetEnabled) {
+                    particle._initialStartSpriteCellID = this_1.startSpriteCellID;
+                    particle._initialEndSpriteCellID = this_1.endSpriteCellID;
+                }
+            };
+            var this_1 = this, step;
+            for (var index = 0; index < newParticles; index++) {
+                var state_1 = _loop_1();
+                if (state_1 === "break")
+                    break;
             }
         };
         /** @hidden */

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

@@ -19,6 +19,7 @@
   - Added support for pre-warming. [Doc](https://doc.babylonjs.com/babylon101/particles#pre-warming)
   - Added support for `minInitialRotation` and `maxInitialRotation`. [Doc](https://doc.babylonjs.com/babylon101/particles#rotation)
   - Added support for size gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#size)
+  - Added support for life time gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#lifetime)
 
 ## Updates
 

+ 10 - 2
src/Particles/babylon.particle.ts

@@ -67,6 +67,10 @@
         public _initialSize: number;
 
         /** @hidden */
+        public _initialStartSpriteCellID: number;
+        public _initialEndSpriteCellID: number;
+
+        /** @hidden */
         public _currentColorGradient: Nullable<ColorGradient>;
         /** @hidden */
         public _currentColor1 = new Color4(0, 0, 0, 0);
@@ -104,10 +108,10 @@
          * Defines how the sprite cell index is updated for the particle
          */
         public updateCellIndex(): void {
-            let dist = (this.particleSystem.endSpriteCellID - this.particleSystem.startSpriteCellID);
+            let dist = (this._initialEndSpriteCellID - this._initialStartSpriteCellID);
             let ratio = Scalar.Clamp(((this.age * this.particleSystem.spriteCellChangeSpeed) / this.lifeTime) % this.lifeTime);
 
-            this.cellIndex = this.particleSystem.startSpriteCellID + (ratio * dist) | 0;
+            this.cellIndex = this._initialStartSpriteCellID + (ratio * dist) | 0;
         }
 
         /**
@@ -146,6 +150,10 @@
                 other._currentSize1 = this._currentSize1;
                 other._currentSize2 = this._currentSize2;
             }
+            if (this.particleSystem.isAnimationSheetEnabled) {
+                other._initialStartSpriteCellID = this._initialStartSpriteCellID;
+                other._initialEndSpriteCellID = this._initialEndSpriteCellID;
+            }
         }
     }
 } 

+ 97 - 31
src/Particles/babylon.particleSystem.ts

@@ -207,6 +207,15 @@
         }        
 
         /**
+         * Gets the current list of life time gradients.
+         * You must use addLifeTimeGradient and removeLifeTimeGradient to udpate this list
+         * @returns the list of life time gradients
+         */
+        public getLifeTimeGradients(): Nullable<Array<FactorGradient>> {
+            return this._lifeTimeGradients;
+        }          
+
+        /**
          * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
          * This only works when particleEmitterTyps is a BoxParticleEmitter
          */
@@ -533,6 +542,65 @@
             }
         }
 
+        private _addFactorGradient(factorGradients: FactorGradient[], gradient: number, factor: number, factor2?: number) {
+            let newGradient = new FactorGradient();
+            newGradient.gradient = gradient;
+            newGradient.factor1 = factor;
+            newGradient.factor2 = factor2;
+            factorGradients.push(newGradient);
+
+            factorGradients.sort((a, b) => {
+                if (a.gradient < b.gradient) {
+                    return -1;
+                } else if (a.gradient > b.gradient) {
+                    return 1;
+                }
+
+                return 0;
+            });            
+        }
+
+        private _removeFactorGradient(factorGradients: Nullable<FactorGradient[]>, gradient: number) {
+            if (!factorGradients) {
+                return;
+            }
+
+            let index = 0;
+            for (var factorGradient of factorGradients) {
+                if (factorGradient.gradient === gradient) {
+                    factorGradients.splice(index, 1);
+                    break;
+                }
+                index++;
+            }
+        }
+
+        /**
+         * Adds a new life time gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the life time factor to affect to the specified gradient         
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         */
+        public addLifeTimeGradient(gradient: number, factor: number, factor2?: number): ParticleSystem {
+            if (!this._lifeTimeGradients) {
+                this._lifeTimeGradients = [];
+            }
+
+            this._addFactorGradient(this._lifeTimeGradients, gradient, factor, factor2);
+
+            return this;
+        }
+
+        /**
+         * Remove a specific life time gradient
+         * @param gradient defines the gradient to remove
+         */
+        public removeLifeTimeGradient(gradient: number): ParticleSystem {
+            this._removeFactorGradient(this._lifeTimeGradients, gradient);
+
+            return this;
+        }       
+
         /**
          * Adds a new size gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -544,21 +612,7 @@
                 this._sizeGradients = [];
             }
 
-            let sizeGradient = new FactorGradient();
-            sizeGradient.gradient = gradient;
-            sizeGradient.factor1 = factor;
-            sizeGradient.factor2 = factor2;
-            this._sizeGradients.push(sizeGradient);
-
-            this._sizeGradients.sort((a, b) => {
-                if (a.gradient < b.gradient) {
-                    return -1;
-                } else if (a.gradient > b.gradient) {
-                    return 1;
-                }
-
-                return 0;
-            });
+            this._addFactorGradient(this._sizeGradients, gradient, factor, factor2);
 
             return this;
         }
@@ -568,18 +622,7 @@
          * @param gradient defines the gradient to remove
          */
         public removeSizeGradient(gradient: number): ParticleSystem {
-            if (!this._sizeGradients) {
-                return this;
-            }
-
-            let index = 0;
-            for (var sizeGradient of this._sizeGradients) {
-                if (sizeGradient.gradient === gradient) {
-                    this._sizeGradients.splice(index, 1);
-                    break;
-                }
-                index++;
-            }
+            this._removeFactorGradient(this._sizeGradients, gradient);
 
             return this;
         }        
@@ -900,7 +943,7 @@
             subSystem.start();
         }
 
-        // end of sub system methods
+        // End of sub system methods
 
         private _update(newParticles: number): void {
             // Update current
@@ -929,6 +972,7 @@
 
                 this._particles.push(particle);
 
+                // Emitter
                 let emitPower = Scalar.RandomRange(this.minEmitPower, this.maxEmitPower);
 
                 if (this.startPositionFunction) {
@@ -957,9 +1001,22 @@
 
                 particle.direction.scaleInPlace(emitPower);
 
-                particle.lifeTime = Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
-
+                // Life time
+                if (this.targetStopDuration && this._lifeTimeGradients && this._lifeTimeGradients.length > 0) {
+                    let ratio = Scalar.Clamp(this._actualFrame / this.targetStopDuration);
+                    Tools.GetCurrentGradient(ratio, this._lifeTimeGradients, (currentGradient, nextGradient, scale) => {
+                        let factorGradient1 = (<FactorGradient>currentGradient);
+                        let factorGradient2 = (<FactorGradient>nextGradient);
+                        let lifeTime1 = factorGradient1.getFactor(); 
+                        let lifeTime2 = factorGradient2.getFactor(); 
+                        let gradient = (ratio - factorGradient1.gradient) / (factorGradient2.gradient - factorGradient1.gradient);
+                        particle.lifeTime = Scalar.Lerp(lifeTime1, lifeTime2, gradient);
+                    });
+                } else {
+                    particle.lifeTime = Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
+                }
 
+                // Size
                 if (!this._sizeGradients || this._sizeGradients.length === 0) {
                     particle.size = Scalar.RandomRange(this.minSize, this.maxSize);
                 } else {
@@ -973,12 +1030,15 @@
                         particle._currentSize2 = particle._currentSize1;
                     }
                 }
+                // Size and scale
                 particle._initialSize = particle.size;
                 particle.scale.copyFromFloats(Scalar.RandomRange(this.minScaleX, this.maxScaleX), Scalar.RandomRange(this.minScaleY, this.maxScaleY));
-                particle.angularSpeed = Scalar.RandomRange(this.minAngularSpeed, this.maxAngularSpeed);
 
+                // Angle
+                particle.angularSpeed = Scalar.RandomRange(this.minAngularSpeed, this.maxAngularSpeed);
                 particle.angle = Scalar.RandomRange(this.minInitialRotation, this.maxInitialRotation);
 
+                // Color
                 if (!this._colorGradients || this._colorGradients.length === 0) {
                     var step = Scalar.RandomRange(0, 1.0);
 
@@ -997,6 +1057,12 @@
                         particle._currentColor2.copyFrom(particle.color);
                     }
                 }
+
+                // Sheet
+                if (this._isAnimationSheetEnabled) {
+                    particle._initialStartSpriteCellID = this.startSpriteCellID;
+                    particle._initialEndSpriteCellID = this.endSpriteCellID;
+                }
             }
         }
 

BIN
tests/validation/ReferenceImages/particle helper.png


+ 1 - 7
tests/validation/config.json

@@ -1,12 +1,6 @@
 {
   "root": "https://rawgit.com/BabylonJS/Website/master",
-  "tests": [
-    {
-      "title": "Particle helper",
-      "playgroundId": "#1VGT5D#2",
-      "renderCount": 50,
-      "referenceImage": "particle helper.png"
-    },       
+  "tests": [  
     {
       "title": "Chibi Rex",
       "playgroundId": "#QATUCH#4",