Explorar o código

Initial particle drag support

David Catuhe %!s(int64=7) %!d(string=hai) anos
pai
achega
a47c1abaaa

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 6568 - 6513
dist/preview release/babylon.d.ts


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/babylon.js


+ 94 - 0
dist/preview release/babylon.max.js

@@ -55777,6 +55777,10 @@ var BABYLON;
             this._currentLimitVelocity1 = 0;
             /** @hidden */
             this._currentLimitVelocity2 = 0;
+            /** @hidden */
+            this._currentDrag1 = 0;
+            /** @hidden */
+            this._currentDrag2 = 0;
             if (!this.particleSystem.isAnimationSheetEnabled) {
                 return;
             }
@@ -55846,6 +55850,11 @@ var BABYLON;
                 other._currentLimitVelocity1 = this._currentLimitVelocity1;
                 other._currentLimitVelocity2 = this._currentLimitVelocity2;
             }
+            if (this._currentDragGradient) {
+                other._currentDragGradient = this._currentDragGradient;
+                other._currentDrag1 = this._currentDrag1;
+                other._currentDrag2 = this._currentDrag2;
+            }
             if (this.particleSystem.isAnimationSheetEnabled) {
                 other._initialStartSpriteCellID = this._initialStartSpriteCellID;
                 other._initialEndSpriteCellID = this._initialEndSpriteCellID;
@@ -56026,6 +56035,7 @@ var BABYLON;
             this._angularSpeedGradients = null;
             this._velocityGradients = null;
             this._limitVelocityGradients = null;
+            this._dragGradients = null;
             /** Gets or sets a value indicating the damping to apply if the limit velocity factor is reached */
             this.limitVelocityDamping = 0.4;
             /**
@@ -56075,6 +56085,14 @@ var BABYLON;
             configurable: true
         });
         /**
+         * Gets the current list of drag gradients.
+         * You must use addDragGradient and removeDragGradient to udpate this list
+         * @returns the list of drag gradients
+         */
+        BaseParticleSystem.prototype.getDragGradients = function () {
+            return this._dragGradients;
+        };
+        /**
          * Gets the current list of limit velocity gradients.
          * You must use addLimitVelocityGradient and removeLimitVelocityGradient to udpate this list
          * @returns the list of limit velocity gradients
@@ -56542,6 +56560,20 @@ var BABYLON;
                         // Gravity
                         _this.gravity.scaleToRef(_this._scaledUpdateSpeed, _this._scaledGravity);
                         particle.direction.addInPlace(_this._scaledGravity);
+                        /// Drag
+                        if (_this._dragGradients && _this._dragGradients.length > 0) {
+                            BABYLON.Tools.GetCurrentGradient(ratio, _this._dragGradients, function (currentGradient, nextGradient, scale) {
+                                if (currentGradient !== particle._currentDragGradient) {
+                                    particle._currentDrag1 = particle._currentDrag2;
+                                    particle._currentDrag2 = nextGradient.getFactor();
+                                    particle._currentDragGradient = currentGradient;
+                                }
+                                var drag = BABYLON.Scalar.Lerp(particle._currentDrag1, particle._currentDrag2, scale);
+                                var dragValue = BABYLON.Tmp.Vector3[0];
+                                particle.direction.scaleToRef(1.0 - drag, dragValue);
+                                particle.direction.subtractInPlace(dragValue);
+                            });
+                        }
                         // Size
                         if (_this._sizeGradients && _this._sizeGradients.length > 0) {
                             BABYLON.Tools.GetCurrentGradient(ratio, _this._sizeGradients, function (currentGradient, nextGradient, scale) {
@@ -56749,6 +56781,29 @@ var BABYLON;
             return this;
         };
         /**
+         * Adds a new drag gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the drag value 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
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.addDragGradient = function (gradient, factor, factor2) {
+            if (!this._dragGradients) {
+                this._dragGradients = [];
+            }
+            this._addFactorGradient(this._dragGradients, gradient, factor, factor2);
+            return this;
+        };
+        /**
+         * Remove a specific drag gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.removeDragGradient = function (gradient) {
+            this._removeFactorGradient(this._dragGradients, gradient);
+            return this;
+        };
+        /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
          * @param color defines the color to affect to the specified gradient
@@ -57123,6 +57178,17 @@ var BABYLON;
                         particle._currentLimitVelocity2 = particle._currentLimitVelocity1;
                     }
                 }
+                // Drag
+                if (this_1._dragGradients && this_1._dragGradients.length > 0) {
+                    particle._currentDragGradient = this_1._dragGradients[0];
+                    particle._currentDrag1 = particle._currentDragGradient.getFactor();
+                    if (this_1._dragGradients.length > 1) {
+                        particle._currentDrag2 = this_1._dragGradients[1].getFactor();
+                    }
+                    else {
+                        particle._currentDrag2 = particle._currentDrag1;
+                    }
+                }
                 // Color
                 if (!this_1._colorGradients || this_1._colorGradients.length === 0) {
                     step = BABYLON.Scalar.RandomRange(0, 1.0);
@@ -61435,6 +61501,34 @@ var BABYLON;
             this._limitVelocityGradientsTexture = null;
             return this;
         };
+        /**
+         * Adds a new drag gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the drag value to affect to the specified gradient
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.addDragGradient = function (gradient, factor) {
+            if (!this._dragGradients) {
+                this._dragGradients = [];
+            }
+            this._addFactorGradient(this._dragGradients, gradient, factor);
+            if (this._dragGradientsTexture) {
+                this._dragGradientsTexture.dispose();
+                this._dragGradientsTexture = null;
+            }
+            this._releaseBuffers();
+            return this;
+        };
+        /**
+         * Remove a specific drag gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.removeDragGradient = function (gradient) {
+            this._removeGradient(gradient, this._dragGradients, this._dragGradientsTexture);
+            this._dragGradientsTexture = null;
+            return this;
+        };
         GPUParticleSystem.prototype._reset = function () {
             this._releaseBuffers();
         };

+ 94 - 0
dist/preview release/babylon.no-module.max.js

@@ -55744,6 +55744,10 @@ var BABYLON;
             this._currentLimitVelocity1 = 0;
             /** @hidden */
             this._currentLimitVelocity2 = 0;
+            /** @hidden */
+            this._currentDrag1 = 0;
+            /** @hidden */
+            this._currentDrag2 = 0;
             if (!this.particleSystem.isAnimationSheetEnabled) {
                 return;
             }
@@ -55813,6 +55817,11 @@ var BABYLON;
                 other._currentLimitVelocity1 = this._currentLimitVelocity1;
                 other._currentLimitVelocity2 = this._currentLimitVelocity2;
             }
+            if (this._currentDragGradient) {
+                other._currentDragGradient = this._currentDragGradient;
+                other._currentDrag1 = this._currentDrag1;
+                other._currentDrag2 = this._currentDrag2;
+            }
             if (this.particleSystem.isAnimationSheetEnabled) {
                 other._initialStartSpriteCellID = this._initialStartSpriteCellID;
                 other._initialEndSpriteCellID = this._initialEndSpriteCellID;
@@ -55993,6 +56002,7 @@ var BABYLON;
             this._angularSpeedGradients = null;
             this._velocityGradients = null;
             this._limitVelocityGradients = null;
+            this._dragGradients = null;
             /** Gets or sets a value indicating the damping to apply if the limit velocity factor is reached */
             this.limitVelocityDamping = 0.4;
             /**
@@ -56042,6 +56052,14 @@ var BABYLON;
             configurable: true
         });
         /**
+         * Gets the current list of drag gradients.
+         * You must use addDragGradient and removeDragGradient to udpate this list
+         * @returns the list of drag gradients
+         */
+        BaseParticleSystem.prototype.getDragGradients = function () {
+            return this._dragGradients;
+        };
+        /**
          * Gets the current list of limit velocity gradients.
          * You must use addLimitVelocityGradient and removeLimitVelocityGradient to udpate this list
          * @returns the list of limit velocity gradients
@@ -56509,6 +56527,20 @@ var BABYLON;
                         // Gravity
                         _this.gravity.scaleToRef(_this._scaledUpdateSpeed, _this._scaledGravity);
                         particle.direction.addInPlace(_this._scaledGravity);
+                        /// Drag
+                        if (_this._dragGradients && _this._dragGradients.length > 0) {
+                            BABYLON.Tools.GetCurrentGradient(ratio, _this._dragGradients, function (currentGradient, nextGradient, scale) {
+                                if (currentGradient !== particle._currentDragGradient) {
+                                    particle._currentDrag1 = particle._currentDrag2;
+                                    particle._currentDrag2 = nextGradient.getFactor();
+                                    particle._currentDragGradient = currentGradient;
+                                }
+                                var drag = BABYLON.Scalar.Lerp(particle._currentDrag1, particle._currentDrag2, scale);
+                                var dragValue = BABYLON.Tmp.Vector3[0];
+                                particle.direction.scaleToRef(1.0 - drag, dragValue);
+                                particle.direction.subtractInPlace(dragValue);
+                            });
+                        }
                         // Size
                         if (_this._sizeGradients && _this._sizeGradients.length > 0) {
                             BABYLON.Tools.GetCurrentGradient(ratio, _this._sizeGradients, function (currentGradient, nextGradient, scale) {
@@ -56716,6 +56748,29 @@ var BABYLON;
             return this;
         };
         /**
+         * Adds a new drag gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the drag value 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
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.addDragGradient = function (gradient, factor, factor2) {
+            if (!this._dragGradients) {
+                this._dragGradients = [];
+            }
+            this._addFactorGradient(this._dragGradients, gradient, factor, factor2);
+            return this;
+        };
+        /**
+         * Remove a specific drag gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.removeDragGradient = function (gradient) {
+            this._removeFactorGradient(this._dragGradients, gradient);
+            return this;
+        };
+        /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
          * @param color defines the color to affect to the specified gradient
@@ -57090,6 +57145,17 @@ var BABYLON;
                         particle._currentLimitVelocity2 = particle._currentLimitVelocity1;
                     }
                 }
+                // Drag
+                if (this_1._dragGradients && this_1._dragGradients.length > 0) {
+                    particle._currentDragGradient = this_1._dragGradients[0];
+                    particle._currentDrag1 = particle._currentDragGradient.getFactor();
+                    if (this_1._dragGradients.length > 1) {
+                        particle._currentDrag2 = this_1._dragGradients[1].getFactor();
+                    }
+                    else {
+                        particle._currentDrag2 = particle._currentDrag1;
+                    }
+                }
                 // Color
                 if (!this_1._colorGradients || this_1._colorGradients.length === 0) {
                     step = BABYLON.Scalar.RandomRange(0, 1.0);
@@ -61402,6 +61468,34 @@ var BABYLON;
             this._limitVelocityGradientsTexture = null;
             return this;
         };
+        /**
+         * Adds a new drag gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the drag value to affect to the specified gradient
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.addDragGradient = function (gradient, factor) {
+            if (!this._dragGradients) {
+                this._dragGradients = [];
+            }
+            this._addFactorGradient(this._dragGradients, gradient, factor);
+            if (this._dragGradientsTexture) {
+                this._dragGradientsTexture.dispose();
+                this._dragGradientsTexture = null;
+            }
+            this._releaseBuffers();
+            return this;
+        };
+        /**
+         * Remove a specific drag gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.removeDragGradient = function (gradient) {
+            this._removeGradient(gradient, this._dragGradients, this._dragGradientsTexture);
+            this._dragGradientsTexture = null;
+            return this;
+        };
         GPUParticleSystem.prototype._reset = function () {
             this._releaseBuffers();
         };

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/babylon.worker.js


+ 94 - 0
dist/preview release/es6.js

@@ -55744,6 +55744,10 @@ var BABYLON;
             this._currentLimitVelocity1 = 0;
             /** @hidden */
             this._currentLimitVelocity2 = 0;
+            /** @hidden */
+            this._currentDrag1 = 0;
+            /** @hidden */
+            this._currentDrag2 = 0;
             if (!this.particleSystem.isAnimationSheetEnabled) {
                 return;
             }
@@ -55813,6 +55817,11 @@ var BABYLON;
                 other._currentLimitVelocity1 = this._currentLimitVelocity1;
                 other._currentLimitVelocity2 = this._currentLimitVelocity2;
             }
+            if (this._currentDragGradient) {
+                other._currentDragGradient = this._currentDragGradient;
+                other._currentDrag1 = this._currentDrag1;
+                other._currentDrag2 = this._currentDrag2;
+            }
             if (this.particleSystem.isAnimationSheetEnabled) {
                 other._initialStartSpriteCellID = this._initialStartSpriteCellID;
                 other._initialEndSpriteCellID = this._initialEndSpriteCellID;
@@ -55993,6 +56002,7 @@ var BABYLON;
             this._angularSpeedGradients = null;
             this._velocityGradients = null;
             this._limitVelocityGradients = null;
+            this._dragGradients = null;
             /** Gets or sets a value indicating the damping to apply if the limit velocity factor is reached */
             this.limitVelocityDamping = 0.4;
             /**
@@ -56042,6 +56052,14 @@ var BABYLON;
             configurable: true
         });
         /**
+         * Gets the current list of drag gradients.
+         * You must use addDragGradient and removeDragGradient to udpate this list
+         * @returns the list of drag gradients
+         */
+        BaseParticleSystem.prototype.getDragGradients = function () {
+            return this._dragGradients;
+        };
+        /**
          * Gets the current list of limit velocity gradients.
          * You must use addLimitVelocityGradient and removeLimitVelocityGradient to udpate this list
          * @returns the list of limit velocity gradients
@@ -56509,6 +56527,20 @@ var BABYLON;
                         // Gravity
                         _this.gravity.scaleToRef(_this._scaledUpdateSpeed, _this._scaledGravity);
                         particle.direction.addInPlace(_this._scaledGravity);
+                        /// Drag
+                        if (_this._dragGradients && _this._dragGradients.length > 0) {
+                            BABYLON.Tools.GetCurrentGradient(ratio, _this._dragGradients, function (currentGradient, nextGradient, scale) {
+                                if (currentGradient !== particle._currentDragGradient) {
+                                    particle._currentDrag1 = particle._currentDrag2;
+                                    particle._currentDrag2 = nextGradient.getFactor();
+                                    particle._currentDragGradient = currentGradient;
+                                }
+                                var drag = BABYLON.Scalar.Lerp(particle._currentDrag1, particle._currentDrag2, scale);
+                                var dragValue = BABYLON.Tmp.Vector3[0];
+                                particle.direction.scaleToRef(1.0 - drag, dragValue);
+                                particle.direction.subtractInPlace(dragValue);
+                            });
+                        }
                         // Size
                         if (_this._sizeGradients && _this._sizeGradients.length > 0) {
                             BABYLON.Tools.GetCurrentGradient(ratio, _this._sizeGradients, function (currentGradient, nextGradient, scale) {
@@ -56716,6 +56748,29 @@ var BABYLON;
             return this;
         };
         /**
+         * Adds a new drag gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the drag value 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
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.addDragGradient = function (gradient, factor, factor2) {
+            if (!this._dragGradients) {
+                this._dragGradients = [];
+            }
+            this._addFactorGradient(this._dragGradients, gradient, factor, factor2);
+            return this;
+        };
+        /**
+         * Remove a specific drag gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.removeDragGradient = function (gradient) {
+            this._removeFactorGradient(this._dragGradients, gradient);
+            return this;
+        };
+        /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
          * @param color defines the color to affect to the specified gradient
@@ -57090,6 +57145,17 @@ var BABYLON;
                         particle._currentLimitVelocity2 = particle._currentLimitVelocity1;
                     }
                 }
+                // Drag
+                if (this_1._dragGradients && this_1._dragGradients.length > 0) {
+                    particle._currentDragGradient = this_1._dragGradients[0];
+                    particle._currentDrag1 = particle._currentDragGradient.getFactor();
+                    if (this_1._dragGradients.length > 1) {
+                        particle._currentDrag2 = this_1._dragGradients[1].getFactor();
+                    }
+                    else {
+                        particle._currentDrag2 = particle._currentDrag1;
+                    }
+                }
                 // Color
                 if (!this_1._colorGradients || this_1._colorGradients.length === 0) {
                     step = BABYLON.Scalar.RandomRange(0, 1.0);
@@ -61402,6 +61468,34 @@ var BABYLON;
             this._limitVelocityGradientsTexture = null;
             return this;
         };
+        /**
+         * Adds a new drag gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the drag value to affect to the specified gradient
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.addDragGradient = function (gradient, factor) {
+            if (!this._dragGradients) {
+                this._dragGradients = [];
+            }
+            this._addFactorGradient(this._dragGradients, gradient, factor);
+            if (this._dragGradientsTexture) {
+                this._dragGradientsTexture.dispose();
+                this._dragGradientsTexture = null;
+            }
+            this._releaseBuffers();
+            return this;
+        };
+        /**
+         * Remove a specific drag gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.removeDragGradient = function (gradient) {
+            this._removeGradient(gradient, this._dragGradients, this._dragGradientsTexture);
+            this._dragGradientsTexture = null;
+            return this;
+        };
         GPUParticleSystem.prototype._reset = function () {
             this._releaseBuffers();
         };

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

@@ -924,7 +924,7 @@ declare module BabylonViewer {
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 declare module BabylonViewer {
@@ -1558,20 +1558,6 @@ declare module BabylonViewer {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 declare module BabylonViewer {
-    /**
-        * A custom upgrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedUpgrade(sceneManager: SceneManager): boolean;
-    /**
-        * A custom degrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedDegrade(sceneManager: SceneManager): boolean;
-}
-declare module BabylonViewer {
 }
 declare module BabylonViewer {
     export interface IEnvironmentMapConfiguration {

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -985,14 +985,13 @@ declare module 'babylonjs-viewer/templating/viewerTemplatePlugin' {
 }
 
 declare module 'babylonjs-viewer/optimizer/custom' {
-    import { extendedUpgrade } from "babylonjs-viewer/optimizer/custom/extended";
     import { SceneManager } from "babylonjs-viewer/managers/sceneManager";
     /**
       *
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 
@@ -1663,22 +1662,6 @@ declare module 'babylonjs-viewer/loader/plugins' {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 
-declare module 'babylonjs-viewer/optimizer/custom/extended' {
-    import { SceneManager } from 'babylonjs-viewer/managers/sceneManager';
-    /**
-        * A custom upgrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedUpgrade(sceneManager: SceneManager): boolean;
-    /**
-        * A custom degrade-oriented function configuration for the scene optimizer.
-        *
-        * @param viewer the viewer to optimize
-        */
-    export function extendedDegrade(sceneManager: SceneManager): boolean;
-}
-
 declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/cameraConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration';

+ 14 - 0
src/Particles/babylon.IParticleSystem.ts

@@ -362,5 +362,19 @@ module BABYLON {
          * @returns the current particle system
          */
         removeLimitVelocityGradient(gradient: number): IParticleSystem;        
+        /**
+         * Adds a new drag gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the drag 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
+         * @returns the current particle system
+         */
+        addDragGradient(gradient: number, factor: number, factor2?: number): IParticleSystem;
+        /**
+         * Remove a specific drag gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        removeDragGradient(gradient: number): IParticleSystem;               
     }  
 }

+ 11 - 1
src/Particles/babylon.baseParticleSystem.ts

@@ -240,10 +240,20 @@ module BABYLON {
         protected _angularSpeedGradients: Nullable<Array<FactorGradient>> = null;
         protected _velocityGradients: Nullable<Array<FactorGradient>> = null;
         protected _limitVelocityGradients: Nullable<Array<FactorGradient>> = null;
+        protected _dragGradients: Nullable<Array<FactorGradient>> = null;
+
+        /**
+         * Gets the current list of drag gradients.
+         * You must use addDragGradient and removeDragGradient to udpate this list
+         * @returns the list of drag gradients
+         */
+        public getDragGradients(): Nullable<Array<FactorGradient>> {
+            return this._dragGradients;
+        }   
 
         /** Gets or sets a value indicating the damping to apply if the limit velocity factor is reached */
         public limitVelocityDamping = 0.4;
-
+        
         /**
          * Gets the current list of limit velocity gradients.
          * You must use addLimitVelocityGradient and removeLimitVelocityGradient to udpate this list

+ 36 - 0
src/Particles/babylon.gpuParticleSystem.ts

@@ -234,6 +234,7 @@
         private _sizeGradientsTexture: RawTexture;             
         private _velocityGradientsTexture: RawTexture;    
         private _limitVelocityGradientsTexture: RawTexture;    
+        private _dragGradientsTexture: RawTexture;  
 
         private _addFactorGradient(factorGradients: FactorGradient[], gradient: number, factor: number) {
             let valueGradient = new FactorGradient();
@@ -395,6 +396,41 @@
         }
 
         /**
+         * Adds a new drag gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the drag value to affect to the specified gradient    
+         * @returns the current particle system     
+         */
+        public addDragGradient(gradient: number, factor: number): GPUParticleSystem {
+            if (!this._dragGradients) {
+                this._dragGradients = [];
+            }
+
+            this._addFactorGradient(this._dragGradients, gradient, factor);
+
+            if (this._dragGradientsTexture) {
+                this._dragGradientsTexture.dispose();
+                (<any>this._dragGradientsTexture) = null;
+            }
+
+            this._releaseBuffers();   
+
+            return this;
+        }
+
+        /**
+         * Remove a specific drag gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        public removeDragGradient(gradient: number): GPUParticleSystem {
+            this._removeGradient(gradient, this._dragGradients, this._dragGradientsTexture);
+            (<any>this._dragGradientsTexture) = null;
+
+            return this;
+        }        
+
+        /**
          * Instantiates a GPU particle system.
          * 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.
          * @param name The name of the particle system

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

@@ -100,7 +100,14 @@
         /** @hidden */
         public _currentLimitVelocity1 = 0;
         /** @hidden */
-        public _currentLimitVelocity2 = 0;            
+        public _currentLimitVelocity2 = 0;       
+        
+        /** @hidden */
+        public _currentDragGradient: Nullable<FactorGradient>;
+        /** @hidden */
+        public _currentDrag1 = 0;
+        /** @hidden */
+        public _currentDrag2 = 0;  
 
         /**
          * Creates a new instance Particle
@@ -182,7 +189,12 @@
                 other._currentLimitVelocityGradient = this._currentLimitVelocityGradient;
                 other._currentLimitVelocity1 = this._currentLimitVelocity1;
                 other._currentLimitVelocity2 = this._currentLimitVelocity2;
-            }                           
+            }     
+            if (this._currentDragGradient) {
+                other._currentDragGradient = this._currentDragGradient;
+                other._currentDrag1 = this._currentDrag1;
+                other._currentDrag2 = this._currentDrag2;
+            }                                   
             if (this.particleSystem.isAnimationSheetEnabled) {
                 other._initialStartSpriteCellID = this._initialStartSpriteCellID;
                 other._initialEndSpriteCellID = this._initialEndSpriteCellID;

+ 58 - 1
src/Particles/babylon.particleSystem.ts

@@ -262,6 +262,23 @@
                         this.gravity.scaleToRef(this._scaledUpdateSpeed, this._scaledGravity);
                         particle.direction.addInPlace(this._scaledGravity);
 
+                        /// Drag
+                        if (this._dragGradients && this._dragGradients.length > 0) {                  
+                            Tools.GetCurrentGradient(ratio, this._dragGradients, (currentGradient, nextGradient, scale) => {
+                                if (currentGradient !== particle._currentDragGradient) {
+                                    particle._currentDrag1 = particle._currentDrag2;
+                                    particle._currentDrag2 = (<FactorGradient>nextGradient).getFactor();    
+                                    particle._currentDragGradient = (<FactorGradient>currentGradient);
+                                }                                
+                                
+                                let drag = Scalar.Lerp(particle._currentDrag1, particle._currentDrag2, scale);
+
+                                let dragValue = Tmp.Vector3[0];
+                                particle.direction.scaleToRef(1.0 - drag, dragValue);
+                                particle.direction.subtractInPlace(dragValue);
+                            });
+                        }                          
+
                         // Size
                         if (this._sizeGradients && this._sizeGradients.length > 0) {                  
                             Tools.GetCurrentGradient(ratio, this._sizeGradients, (currentGradient, nextGradient, scale) => {
@@ -454,7 +471,35 @@
             this._removeFactorGradient(this._limitVelocityGradients, gradient);
 
             return this;
-        }            
+        }       
+        
+        /**
+         * Adds a new drag gradient
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the drag value 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
+         * @returns the current particle system
+         */
+        public addDragGradient(gradient: number, factor: number, factor2?: number): IParticleSystem {
+            if (!this._dragGradients) {
+                this._dragGradients = [];
+            }
+
+            this._addFactorGradient(this._dragGradients, gradient, factor, factor2);
+
+            return this;
+        }
+
+        /**
+         * Remove a specific drag gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        public removeDragGradient(gradient: number): IParticleSystem {
+            this._removeFactorGradient(this._dragGradients, gradient);
+
+            return this;
+        }           
 
         /**
          * Adds a new color gradient
@@ -924,6 +969,18 @@
                     }
                 }                   
 
+                // Drag
+                if (this._dragGradients && this._dragGradients.length > 0) {
+                    particle._currentDragGradient = this._dragGradients[0];
+                    particle._currentDrag1 = particle._currentDragGradient.getFactor();
+
+                    if (this._dragGradients.length > 1) {
+                        particle._currentDrag2 = this._dragGradients[1].getFactor();
+                    } else {
+                        particle._currentDrag2 = particle._currentDrag1;
+                    }
+                }          
+
                 // Color
                 if (!this._colorGradients || this._colorGradients.length === 0) {
                     var step = Scalar.RandomRange(0, 1.0);

BIN=BIN
tests/validation/ReferenceImages/ssao2.png