瀏覽代碼

Added particle size gradients

David Catuhe 7 年之前
父節點
當前提交
9b59e2671d

文件差異過大導致無法顯示
+ 7479 - 7464
dist/preview release/babylon.d.ts


文件差異過大導致無法顯示
+ 7 - 7
dist/preview release/babylon.js


+ 72 - 10
dist/preview release/babylon.max.js

@@ -55171,6 +55171,12 @@ var BABYLON;
         }
         return ColorGradient;
     }());
+    /** @hidden */
+    var FactorGradient = /** @class */ (function () {
+        function FactorGradient() {
+        }
+        return FactorGradient;
+    }());
     /**
      * This represents a particle system in Babylon.
      * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
@@ -55313,6 +55319,7 @@ var BABYLON;
              */
             this.gravity = BABYLON.Vector3.Zero();
             this._colorGradients = null;
+            this._sizeGradients = null;
             /**
              * Random color of each particle after it has been emitted, between color1 and color2 vectors
              */
@@ -55433,17 +55440,12 @@ var BABYLON;
                         continue;
                     }
                     else {
+                        var ratio = particle.age / particle.lifeTime;
+                        // Color
                         if (_this._colorGradients && _this._colorGradients.length > 0) {
-                            var ratio = particle.age / particle.lifeTime;
-                            for (var gradientIndex = 0; gradientIndex < _this._colorGradients.length - 1; gradientIndex++) {
-                                var currentGradient = _this._colorGradients[gradientIndex];
-                                var nextGradient = _this._colorGradients[gradientIndex + 1];
-                                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
-                                    var scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
-                                    BABYLON.Color4.LerpToRef(currentGradient.color, nextGradient.color, scale, particle.color);
-                                    break;
-                                }
-                            }
+                            _this._getCurrentGradient(ratio, _this._colorGradients, function (currentGradient, nextGradient, scale) {
+                                BABYLON.Color4.LerpToRef(currentGradient.color, nextGradient.color, scale, particle.color);
+                            });
                         }
                         else {
                             particle.colorStep.scaleToRef(_this._scaledUpdateSpeed, _this._scaledColorStep);
@@ -55457,6 +55459,12 @@ var BABYLON;
                         particle.position.addInPlace(_this._scaledDirection);
                         _this.gravity.scaleToRef(_this._scaledUpdateSpeed, _this._scaledGravity);
                         particle.direction.addInPlace(_this._scaledGravity);
+                        // Gradient
+                        if (_this._sizeGradients && _this._sizeGradients.length > 0) {
+                            _this._getCurrentGradient(ratio, _this._sizeGradients, function (currentGradient, nextGradient, scale) {
+                                particle.size = particle._initialSize * BABYLON.Scalar.Lerp(currentGradient.factor, nextGradient.factor, scale);
+                            });
+                        }
                         if (_this._isAnimationSheetEnabled) {
                             particle.updateCellIndex(_this._scaledUpdateSpeed);
                         }
@@ -55598,6 +55606,59 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem.prototype._getCurrentGradient = function (ratio, gradients, updateFunc) {
+            for (var gradientIndex = 0; gradientIndex < gradients.length - 1; gradientIndex++) {
+                var currentGradient = gradients[gradientIndex];
+                var nextGradient = gradients[gradientIndex + 1];
+                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
+                    var scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
+                    updateFunc(currentGradient, nextGradient, scale);
+                }
+            }
+        };
+        /**
+         * Adds a new size gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the size factor to affect to the specified gradient
+         */
+        ParticleSystem.prototype.addSizeGradient = function (gradient, factor) {
+            if (!this._sizeGradients) {
+                this._sizeGradients = [];
+            }
+            var sizeGradient = new FactorGradient();
+            sizeGradient.gradient = gradient;
+            sizeGradient.factor = factor;
+            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;
+            });
+            return this;
+        };
+        /**
+         * Remove a specific size gradient
+         * @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++;
+            }
+            return this;
+        };
         /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -55883,6 +55944,7 @@ var BABYLON;
                 particle.direction.scaleInPlace(emitPower);
                 particle.lifeTime = BABYLON.Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
                 particle.size = BABYLON.Scalar.RandomRange(this.minSize, this.maxSize);
+                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);

+ 72 - 10
dist/preview release/babylon.no-module.max.js

@@ -55138,6 +55138,12 @@ var BABYLON;
         }
         return ColorGradient;
     }());
+    /** @hidden */
+    var FactorGradient = /** @class */ (function () {
+        function FactorGradient() {
+        }
+        return FactorGradient;
+    }());
     /**
      * This represents a particle system in Babylon.
      * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
@@ -55280,6 +55286,7 @@ var BABYLON;
              */
             this.gravity = BABYLON.Vector3.Zero();
             this._colorGradients = null;
+            this._sizeGradients = null;
             /**
              * Random color of each particle after it has been emitted, between color1 and color2 vectors
              */
@@ -55400,17 +55407,12 @@ var BABYLON;
                         continue;
                     }
                     else {
+                        var ratio = particle.age / particle.lifeTime;
+                        // Color
                         if (_this._colorGradients && _this._colorGradients.length > 0) {
-                            var ratio = particle.age / particle.lifeTime;
-                            for (var gradientIndex = 0; gradientIndex < _this._colorGradients.length - 1; gradientIndex++) {
-                                var currentGradient = _this._colorGradients[gradientIndex];
-                                var nextGradient = _this._colorGradients[gradientIndex + 1];
-                                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
-                                    var scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
-                                    BABYLON.Color4.LerpToRef(currentGradient.color, nextGradient.color, scale, particle.color);
-                                    break;
-                                }
-                            }
+                            _this._getCurrentGradient(ratio, _this._colorGradients, function (currentGradient, nextGradient, scale) {
+                                BABYLON.Color4.LerpToRef(currentGradient.color, nextGradient.color, scale, particle.color);
+                            });
                         }
                         else {
                             particle.colorStep.scaleToRef(_this._scaledUpdateSpeed, _this._scaledColorStep);
@@ -55424,6 +55426,12 @@ var BABYLON;
                         particle.position.addInPlace(_this._scaledDirection);
                         _this.gravity.scaleToRef(_this._scaledUpdateSpeed, _this._scaledGravity);
                         particle.direction.addInPlace(_this._scaledGravity);
+                        // Gradient
+                        if (_this._sizeGradients && _this._sizeGradients.length > 0) {
+                            _this._getCurrentGradient(ratio, _this._sizeGradients, function (currentGradient, nextGradient, scale) {
+                                particle.size = particle._initialSize * BABYLON.Scalar.Lerp(currentGradient.factor, nextGradient.factor, scale);
+                            });
+                        }
                         if (_this._isAnimationSheetEnabled) {
                             particle.updateCellIndex(_this._scaledUpdateSpeed);
                         }
@@ -55565,6 +55573,59 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem.prototype._getCurrentGradient = function (ratio, gradients, updateFunc) {
+            for (var gradientIndex = 0; gradientIndex < gradients.length - 1; gradientIndex++) {
+                var currentGradient = gradients[gradientIndex];
+                var nextGradient = gradients[gradientIndex + 1];
+                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
+                    var scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
+                    updateFunc(currentGradient, nextGradient, scale);
+                }
+            }
+        };
+        /**
+         * Adds a new size gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the size factor to affect to the specified gradient
+         */
+        ParticleSystem.prototype.addSizeGradient = function (gradient, factor) {
+            if (!this._sizeGradients) {
+                this._sizeGradients = [];
+            }
+            var sizeGradient = new FactorGradient();
+            sizeGradient.gradient = gradient;
+            sizeGradient.factor = factor;
+            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;
+            });
+            return this;
+        };
+        /**
+         * Remove a specific size gradient
+         * @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++;
+            }
+            return this;
+        };
         /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -55850,6 +55911,7 @@ var BABYLON;
                 particle.direction.scaleInPlace(emitPower);
                 particle.lifeTime = BABYLON.Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
                 particle.size = BABYLON.Scalar.RandomRange(this.minSize, this.maxSize);
+                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);

文件差異過大導致無法顯示
+ 7 - 7
dist/preview release/babylon.worker.js


+ 72 - 10
dist/preview release/es6.js

@@ -55138,6 +55138,12 @@ var BABYLON;
         }
         return ColorGradient;
     }());
+    /** @hidden */
+    var FactorGradient = /** @class */ (function () {
+        function FactorGradient() {
+        }
+        return FactorGradient;
+    }());
     /**
      * This represents a particle system in Babylon.
      * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
@@ -55280,6 +55286,7 @@ var BABYLON;
              */
             this.gravity = BABYLON.Vector3.Zero();
             this._colorGradients = null;
+            this._sizeGradients = null;
             /**
              * Random color of each particle after it has been emitted, between color1 and color2 vectors
              */
@@ -55400,17 +55407,12 @@ var BABYLON;
                         continue;
                     }
                     else {
+                        var ratio = particle.age / particle.lifeTime;
+                        // Color
                         if (_this._colorGradients && _this._colorGradients.length > 0) {
-                            var ratio = particle.age / particle.lifeTime;
-                            for (var gradientIndex = 0; gradientIndex < _this._colorGradients.length - 1; gradientIndex++) {
-                                var currentGradient = _this._colorGradients[gradientIndex];
-                                var nextGradient = _this._colorGradients[gradientIndex + 1];
-                                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
-                                    var scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
-                                    BABYLON.Color4.LerpToRef(currentGradient.color, nextGradient.color, scale, particle.color);
-                                    break;
-                                }
-                            }
+                            _this._getCurrentGradient(ratio, _this._colorGradients, function (currentGradient, nextGradient, scale) {
+                                BABYLON.Color4.LerpToRef(currentGradient.color, nextGradient.color, scale, particle.color);
+                            });
                         }
                         else {
                             particle.colorStep.scaleToRef(_this._scaledUpdateSpeed, _this._scaledColorStep);
@@ -55424,6 +55426,12 @@ var BABYLON;
                         particle.position.addInPlace(_this._scaledDirection);
                         _this.gravity.scaleToRef(_this._scaledUpdateSpeed, _this._scaledGravity);
                         particle.direction.addInPlace(_this._scaledGravity);
+                        // Gradient
+                        if (_this._sizeGradients && _this._sizeGradients.length > 0) {
+                            _this._getCurrentGradient(ratio, _this._sizeGradients, function (currentGradient, nextGradient, scale) {
+                                particle.size = particle._initialSize * BABYLON.Scalar.Lerp(currentGradient.factor, nextGradient.factor, scale);
+                            });
+                        }
                         if (_this._isAnimationSheetEnabled) {
                             particle.updateCellIndex(_this._scaledUpdateSpeed);
                         }
@@ -55565,6 +55573,59 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem.prototype._getCurrentGradient = function (ratio, gradients, updateFunc) {
+            for (var gradientIndex = 0; gradientIndex < gradients.length - 1; gradientIndex++) {
+                var currentGradient = gradients[gradientIndex];
+                var nextGradient = gradients[gradientIndex + 1];
+                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
+                    var scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
+                    updateFunc(currentGradient, nextGradient, scale);
+                }
+            }
+        };
+        /**
+         * Adds a new size gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the size factor to affect to the specified gradient
+         */
+        ParticleSystem.prototype.addSizeGradient = function (gradient, factor) {
+            if (!this._sizeGradients) {
+                this._sizeGradients = [];
+            }
+            var sizeGradient = new FactorGradient();
+            sizeGradient.gradient = gradient;
+            sizeGradient.factor = factor;
+            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;
+            });
+            return this;
+        };
+        /**
+         * Remove a specific size gradient
+         * @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++;
+            }
+            return this;
+        };
         /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -55850,6 +55911,7 @@ var BABYLON;
                 particle.direction.scaleInPlace(emitPower);
                 particle.lifeTime = BABYLON.Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
                 particle.size = BABYLON.Scalar.RandomRange(this.minSize, this.maxSize);
+                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);

文件差異過大導致無法顯示
+ 7 - 7
dist/preview release/viewer/babylon.viewer.js


+ 72 - 10
dist/preview release/viewer/babylon.viewer.max.js

@@ -55259,6 +55259,12 @@ var BABYLON;
         }
         return ColorGradient;
     }());
+    /** @hidden */
+    var FactorGradient = /** @class */ (function () {
+        function FactorGradient() {
+        }
+        return FactorGradient;
+    }());
     /**
      * This represents a particle system in Babylon.
      * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
@@ -55401,6 +55407,7 @@ var BABYLON;
              */
             this.gravity = BABYLON.Vector3.Zero();
             this._colorGradients = null;
+            this._sizeGradients = null;
             /**
              * Random color of each particle after it has been emitted, between color1 and color2 vectors
              */
@@ -55521,17 +55528,12 @@ var BABYLON;
                         continue;
                     }
                     else {
+                        var ratio = particle.age / particle.lifeTime;
+                        // Color
                         if (_this._colorGradients && _this._colorGradients.length > 0) {
-                            var ratio = particle.age / particle.lifeTime;
-                            for (var gradientIndex = 0; gradientIndex < _this._colorGradients.length - 1; gradientIndex++) {
-                                var currentGradient = _this._colorGradients[gradientIndex];
-                                var nextGradient = _this._colorGradients[gradientIndex + 1];
-                                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
-                                    var scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
-                                    BABYLON.Color4.LerpToRef(currentGradient.color, nextGradient.color, scale, particle.color);
-                                    break;
-                                }
-                            }
+                            _this._getCurrentGradient(ratio, _this._colorGradients, function (currentGradient, nextGradient, scale) {
+                                BABYLON.Color4.LerpToRef(currentGradient.color, nextGradient.color, scale, particle.color);
+                            });
                         }
                         else {
                             particle.colorStep.scaleToRef(_this._scaledUpdateSpeed, _this._scaledColorStep);
@@ -55545,6 +55547,12 @@ var BABYLON;
                         particle.position.addInPlace(_this._scaledDirection);
                         _this.gravity.scaleToRef(_this._scaledUpdateSpeed, _this._scaledGravity);
                         particle.direction.addInPlace(_this._scaledGravity);
+                        // Gradient
+                        if (_this._sizeGradients && _this._sizeGradients.length > 0) {
+                            _this._getCurrentGradient(ratio, _this._sizeGradients, function (currentGradient, nextGradient, scale) {
+                                particle.size = particle._initialSize * BABYLON.Scalar.Lerp(currentGradient.factor, nextGradient.factor, scale);
+                            });
+                        }
                         if (_this._isAnimationSheetEnabled) {
                             particle.updateCellIndex(_this._scaledUpdateSpeed);
                         }
@@ -55686,6 +55694,59 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem.prototype._getCurrentGradient = function (ratio, gradients, updateFunc) {
+            for (var gradientIndex = 0; gradientIndex < gradients.length - 1; gradientIndex++) {
+                var currentGradient = gradients[gradientIndex];
+                var nextGradient = gradients[gradientIndex + 1];
+                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
+                    var scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
+                    updateFunc(currentGradient, nextGradient, scale);
+                }
+            }
+        };
+        /**
+         * Adds a new size gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the size factor to affect to the specified gradient
+         */
+        ParticleSystem.prototype.addSizeGradient = function (gradient, factor) {
+            if (!this._sizeGradients) {
+                this._sizeGradients = [];
+            }
+            var sizeGradient = new FactorGradient();
+            sizeGradient.gradient = gradient;
+            sizeGradient.factor = factor;
+            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;
+            });
+            return this;
+        };
+        /**
+         * Remove a specific size gradient
+         * @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++;
+            }
+            return this;
+        };
         /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -55971,6 +56032,7 @@ var BABYLON;
                 particle.direction.scaleInPlace(emitPower);
                 particle.lifeTime = BABYLON.Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
                 particle.size = BABYLON.Scalar.RandomRange(this.minSize, this.maxSize);
+                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);

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

@@ -18,6 +18,7 @@
   - Added support for color gradients. [Doc](http://doc.babylonjs.com/babylon101/particles#particle-colors)
   - Added support for pre-warming. [Doc](http://doc.babylonjs.com/babylon101/particles#pre-warming)
   - Added support for `minInitialRotation` and `maxInitialRotation`. [Doc](http://doc.babylonjs.com/babylon101/particles#rotation)
+  - Added support for size gradients. [Doc](http://doc.babylonjs.com/babylon101/particles#size)
 
 ## Updates
 

+ 3 - 0
src/Particles/babylon.particle.ts

@@ -65,6 +65,9 @@
         /** @hidden */
         public _initialDirection: Nullable<Vector3>;
 
+        /** @hidden */
+        public _initialSize: number;
+
         /**
          * Creates a new instance Particle
          * @param particleSystem the particle system the particle belongs to

+ 88 - 13
src/Particles/babylon.particleSystem.ts

@@ -1,11 +1,21 @@
 module BABYLON {
 
+    interface IValueGradient {
+        gradient: number;
+    }
+
     /** @hidden */
-    class ColorGradient {
+    class ColorGradient implements IValueGradient {
         public gradient: number;
         public color: Color4;
     }
 
+    /** @hidden */
+    class FactorGradient implements IValueGradient {
+        public gradient: number;
+        public factor: number;
+    }
+
     /**
      * This represents a particle system in Babylon.
      * Particles are often small sprites used to simulate hard-to-reproduce phenomena like fire, smoke, water, or abstract visual effects like magic glitter and faery dust.
@@ -191,6 +201,7 @@
         public gravity = Vector3.Zero();
 
         private _colorGradients: Nullable<Array<ColorGradient>> = null;
+        private _sizeGradients: Nullable<Array<FactorGradient>> = null;
 
        /**
          * Random direction of each particle after it has been emitted, between direction1 and direction2 vectors.
@@ -474,19 +485,13 @@
                         continue;
                     }
                     else {
-                        if (this._colorGradients && this._colorGradients.length > 0) {
-                            let ratio = particle.age / particle.lifeTime;
+                        let ratio = particle.age / particle.lifeTime;
 
-                            for (var gradientIndex = 0; gradientIndex < this._colorGradients.length - 1; gradientIndex++) {
-                                let currentGradient = this._colorGradients[gradientIndex];
-                                let nextGradient = this._colorGradients[gradientIndex + 1];
-
-                                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
-                                    let scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
-                                    Color4.LerpToRef(currentGradient.color, nextGradient.color, scale, particle.color);
-                                    break;
-                               }
-                            }
+                        // Color
+                        if (this._colorGradients && this._colorGradients.length > 0) {
+                            this._getCurrentGradient(ratio, this._colorGradients, (currentGradient, nextGradient, scale) => {
+                                Color4.LerpToRef((<ColorGradient>currentGradient).color, (<ColorGradient>nextGradient).color, scale, particle.color);
+                            });
                         }
                         else {
                             particle.colorStep.scaleToRef(this._scaledUpdateSpeed, this._scaledColorStep);
@@ -504,6 +509,14 @@
                         this.gravity.scaleToRef(this._scaledUpdateSpeed, this._scaledGravity);
                         particle.direction.addInPlace(this._scaledGravity);
 
+                        // Gradient
+                        if (this._sizeGradients && this._sizeGradients.length > 0) {
+                            this._getCurrentGradient(ratio, this._sizeGradients, (currentGradient, nextGradient, scale) => {
+                                particle.size = particle._initialSize * Scalar.Lerp((<FactorGradient>currentGradient).factor, (<FactorGradient>nextGradient).factor, scale);
+                            });
+                        }
+
+
                         if (this._isAnimationSheetEnabled) {
                             particle.updateCellIndex(this._scaledUpdateSpeed);
                         }
@@ -512,6 +525,67 @@
             }
         }
 
+        private _getCurrentGradient(ratio: number, gradients: IValueGradient[], updateFunc: (current: IValueGradient, next: IValueGradient, scale: number) => void) {
+            for (var gradientIndex = 0; gradientIndex < gradients.length - 1; gradientIndex++) {
+                let currentGradient = gradients[gradientIndex];
+                let nextGradient = gradients[gradientIndex + 1];
+
+                if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
+                    let scale =  (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
+                    updateFunc(currentGradient, nextGradient, scale);
+               }
+            }
+        }
+
+        /**
+         * Adds a new size gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the size factor to affect to the specified gradient
+         */
+        public addSizeGradient(gradient: number, factor: number): ParticleSystem {
+            if (!this._sizeGradients) {
+                this._sizeGradients = [];
+            }
+
+            let sizeGradient = new FactorGradient();
+            sizeGradient.gradient = gradient;
+            sizeGradient.factor = factor;
+            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;
+            })
+
+            return this;
+        }
+
+        /**
+         * Remove a specific size gradient
+         * @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++;
+            }
+
+            return this;
+        }        
+
         /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
@@ -885,6 +959,7 @@
                 particle.lifeTime = Scalar.RandomRange(this.minLifeTime, this.maxLifeTime);
 
                 particle.size = Scalar.RandomRange(this.minSize, this.maxSize);
+                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);