David Catuhe 7 gadi atpakaļ
vecāks
revīzija
9a8c0be5bf

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


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


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


+ 103 - 27
dist/preview release/babylon.max.js

@@ -50479,7 +50479,7 @@ var BABYLON;
              */
             this.updateSpeed = 0.01;
             /**
-             * The amount of time the particle system is running (depends of the overall speed above).
+             * The amount of time the particle system is running (depends of the overall update speed).
              */
             this.targetStopDuration = 0;
             /**
@@ -51760,8 +51760,14 @@ var BABYLON;
             this._targetIndex = 0;
             this._currentRenderId = -1;
             this._started = false;
+            this._stopped = false;
             this._timeDelta = 0;
             this._attributesStrideSize = 14;
+            this._actualFrame = 0;
+            /**
+             * List of animations used by the particle system.
+             */
+            this.animations = [];
             /**
             * An event triggered when the system is disposed.
             */
@@ -51771,6 +51777,10 @@ var BABYLON;
              */
             this.updateSpeed = 0.01;
             /**
+             * The amount of time the particle system is running (depends of the overall update speed).
+             */
+            this.targetStopDuration = 0;
+            /**
              * Blend mode use to render the particle, it can be either ParticleSystem.BLENDMODE_ONEONE or ParticleSystem.BLENDMODE_STANDARD.
              */
             this.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
@@ -51855,6 +51865,7 @@ var BABYLON;
             this._randomTexture = new BABYLON.RawTexture(new Float32Array(d), maxTextureSize, 1, BABYLON.Engine.TEXTUREFORMAT_RGBA32F, this._scene, false, false, BABYLON.Texture.NEAREST_SAMPLINGMODE, BABYLON.Engine.TEXTURETYPE_FLOAT);
             this._randomTexture.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE;
             this._randomTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE;
+            this._randomTextureSize = maxTextureSize;
         }
         Object.defineProperty(GPUParticleSystem, "IsSupported", {
             /**
@@ -51869,16 +51880,13 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        Object.defineProperty(GPUParticleSystem.prototype, "capacity", {
-            /**
-             * Gets the maximum number of particles supported by this system
-             */
-            get: function () {
-                return this._capacity;
-            },
-            enumerable: true,
-            configurable: true
-        });
+        /**
+         * Gets the maximum number of particles active at the same time.
+         * @returns The max number of active particles.
+         */
+        GPUParticleSystem.prototype.getCapacity = function () {
+            return this._capacity;
+        };
         Object.defineProperty(GPUParticleSystem.prototype, "activeParticleCount", {
             /**
              * Gets or set the number of active particles
@@ -51904,18 +51912,22 @@ var BABYLON;
          */
         GPUParticleSystem.prototype.start = function () {
             this._started = true;
+            this._stopped = false;
         };
         /**
          * Stops the particle system.
          */
         GPUParticleSystem.prototype.stop = function () {
-            this._started = false;
+            this._stopped = true;
         };
         /**
-         * Animates the particle system for the current frame by emitting new particles and or animating the living ones.
+         * Remove all active particles
          */
-        GPUParticleSystem.prototype.animate = function () {
-            this._timeDelta = this.updateSpeed * this._scene.getAnimationRatio();
+        GPUParticleSystem.prototype.reset = function () {
+            this._releaseBuffers();
+            this._releaseVAOs();
+            this._currentActiveCount = 0;
+            this._targetIndex = 0;
         };
         GPUParticleSystem.prototype._createUpdateVAO = function (source) {
             var updateVertexBuffers = {};
@@ -51973,10 +51985,10 @@ var BABYLON;
                 data.push(0.0);
             }
             // Sprite data
-            var spriteData = new Float32Array([1, 1, 1, 1,
-                -1, 1, 0, 1,
-                -1, -1, 0, 0,
-                1, -1, 1, 0]);
+            var spriteData = new Float32Array([0.5, 0.5, 1, 1,
+                -0.5, 0.5, 0, 1,
+                -0.5, -0.5, 0, 0,
+                0.5, -0.5, 1, 0]);
             // Buffers
             this._buffer0 = new BABYLON.Buffer(engine, data, false, this._attributesStrideSize);
             this._buffer1 = new BABYLON.Buffer(engine, data, false, this._attributesStrideSize);
@@ -52000,10 +52012,27 @@ var BABYLON;
             this._updateEffect = new BABYLON.Effect("gpuUpdateParticles", this._updateEffectOptions, this._scene.getEngine());
         };
         /**
+         * Animates the particle system for the current frame by emitting new particles and or animating the living ones.
+         */
+        GPUParticleSystem.prototype.animate = function () {
+            if (!this._stopped) {
+                this._timeDelta = this.updateSpeed * this._scene.getAnimationRatio();
+                this._actualFrame += this._timeDelta;
+                if (this.targetStopDuration && this._actualFrame >= this.targetStopDuration)
+                    this.stop();
+            }
+            else {
+                this._timeDelta = 0;
+            }
+        };
+        /**
          * Renders the particle system in its current state.
          * @returns the current number of particles
          */
         GPUParticleSystem.prototype.render = function () {
+            if (!this._started) {
+                return 0;
+            }
             if (this.particleEmitterType) {
                 this._recreateUpdateEffect(this.particleEmitterType.getEffectDefines());
             }
@@ -52088,14 +52117,7 @@ var BABYLON;
         GPUParticleSystem.prototype.rebuild = function () {
             this._initialize(true);
         };
-        /**
-         * Disposes the particle system and free the associated resources.
-         */
-        GPUParticleSystem.prototype.dispose = function () {
-            var index = this._scene.particleSystems.indexOf(this);
-            if (index > -1) {
-                this._scene.particleSystems.splice(index, 1);
-            }
+        GPUParticleSystem.prototype._releaseBuffers = function () {
             if (this._buffer0) {
                 this._buffer0.dispose();
                 this._buffer0 = null;
@@ -52104,6 +52126,12 @@ var BABYLON;
                 this._buffer1.dispose();
                 this._buffer1 = null;
             }
+            if (this._spriteBuffer) {
+                this._spriteBuffer.dispose();
+                this._spriteBuffer = null;
+            }
+        };
+        GPUParticleSystem.prototype._releaseVAOs = function () {
             for (var index = 0; index < this._updateVAO.length; index++) {
                 this._engine.releaseVertexArrayObject(this._updateVAO[index]);
             }
@@ -52112,6 +52140,17 @@ var BABYLON;
                 this._engine.releaseVertexArrayObject(this._renderVAO[index]);
             }
             this._renderVAO = [];
+        };
+        /**
+         * Disposes the particle system and free the associated resources.
+         */
+        GPUParticleSystem.prototype.dispose = function () {
+            var index = this._scene.particleSystems.indexOf(this);
+            if (index > -1) {
+                this._scene.particleSystems.splice(index, 1);
+            }
+            this._releaseBuffers();
+            this._releaseVAOs();
             if (this._randomTexture) {
                 this._randomTexture.dispose();
                 this._randomTexture = null;
@@ -52135,6 +52174,43 @@ var BABYLON;
          * @returns the JSON object
          */
         GPUParticleSystem.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.name = this.name;
+            serializationObject.id = this.id;
+            // Emitter
+            if (this.emitter.position) {
+                var emitterMesh = this.emitter;
+                serializationObject.emitterId = emitterMesh.id;
+            }
+            else {
+                var emitterPosition = this.emitter;
+                serializationObject.emitter = emitterPosition.asArray();
+            }
+            serializationObject.capacity = this.getCapacity();
+            if (this.particleTexture) {
+                serializationObject.textureName = this.particleTexture.name;
+            }
+            // Animations
+            BABYLON.Animation.AppendSerializedAnimations(this, serializationObject);
+            // Particle system
+            serializationObject.activeParticleCount = this.activeParticleCount;
+            serializationObject.randomTextureSize = this._randomTextureSize;
+            serializationObject.minSize = this.minSize;
+            serializationObject.maxSize = this.maxSize;
+            serializationObject.minEmitPower = this.minEmitPower;
+            serializationObject.maxEmitPower = this.maxEmitPower;
+            serializationObject.minLifeTime = this.minLifeTime;
+            serializationObject.maxLifeTime = this.maxLifeTime;
+            serializationObject.emitRate = this.emitRate;
+            serializationObject.gravity = this.gravity.asArray();
+            serializationObject.color1 = this.color1.asArray();
+            serializationObject.color2 = this.color2.asArray();
+            serializationObject.colorDead = this.colorDead.asArray();
+            serializationObject.updateSpeed = this.updateSpeed;
+            serializationObject.targetStopDuration = this.targetStopDuration;
+            serializationObject.blendMode = this.blendMode;
+            // Emitters
+            return serializationObject;
         };
         return GPUParticleSystem;
     }());

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


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


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


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


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 2710 - 2721
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


+ 103 - 27
dist/preview release/es6.js

@@ -50465,7 +50465,7 @@ var BABYLON;
              */
             this.updateSpeed = 0.01;
             /**
-             * The amount of time the particle system is running (depends of the overall speed above).
+             * The amount of time the particle system is running (depends of the overall update speed).
              */
             this.targetStopDuration = 0;
             /**
@@ -51746,8 +51746,14 @@ var BABYLON;
             this._targetIndex = 0;
             this._currentRenderId = -1;
             this._started = false;
+            this._stopped = false;
             this._timeDelta = 0;
             this._attributesStrideSize = 14;
+            this._actualFrame = 0;
+            /**
+             * List of animations used by the particle system.
+             */
+            this.animations = [];
             /**
             * An event triggered when the system is disposed.
             */
@@ -51757,6 +51763,10 @@ var BABYLON;
              */
             this.updateSpeed = 0.01;
             /**
+             * The amount of time the particle system is running (depends of the overall update speed).
+             */
+            this.targetStopDuration = 0;
+            /**
              * Blend mode use to render the particle, it can be either ParticleSystem.BLENDMODE_ONEONE or ParticleSystem.BLENDMODE_STANDARD.
              */
             this.blendMode = BABYLON.ParticleSystem.BLENDMODE_ONEONE;
@@ -51841,6 +51851,7 @@ var BABYLON;
             this._randomTexture = new BABYLON.RawTexture(new Float32Array(d), maxTextureSize, 1, BABYLON.Engine.TEXTUREFORMAT_RGBA32F, this._scene, false, false, BABYLON.Texture.NEAREST_SAMPLINGMODE, BABYLON.Engine.TEXTURETYPE_FLOAT);
             this._randomTexture.wrapU = BABYLON.Texture.WRAP_ADDRESSMODE;
             this._randomTexture.wrapV = BABYLON.Texture.WRAP_ADDRESSMODE;
+            this._randomTextureSize = maxTextureSize;
         }
         Object.defineProperty(GPUParticleSystem, "IsSupported", {
             /**
@@ -51855,16 +51866,13 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        Object.defineProperty(GPUParticleSystem.prototype, "capacity", {
-            /**
-             * Gets the maximum number of particles supported by this system
-             */
-            get: function () {
-                return this._capacity;
-            },
-            enumerable: true,
-            configurable: true
-        });
+        /**
+         * Gets the maximum number of particles active at the same time.
+         * @returns The max number of active particles.
+         */
+        GPUParticleSystem.prototype.getCapacity = function () {
+            return this._capacity;
+        };
         Object.defineProperty(GPUParticleSystem.prototype, "activeParticleCount", {
             /**
              * Gets or set the number of active particles
@@ -51890,18 +51898,22 @@ var BABYLON;
          */
         GPUParticleSystem.prototype.start = function () {
             this._started = true;
+            this._stopped = false;
         };
         /**
          * Stops the particle system.
          */
         GPUParticleSystem.prototype.stop = function () {
-            this._started = false;
+            this._stopped = true;
         };
         /**
-         * Animates the particle system for the current frame by emitting new particles and or animating the living ones.
+         * Remove all active particles
          */
-        GPUParticleSystem.prototype.animate = function () {
-            this._timeDelta = this.updateSpeed * this._scene.getAnimationRatio();
+        GPUParticleSystem.prototype.reset = function () {
+            this._releaseBuffers();
+            this._releaseVAOs();
+            this._currentActiveCount = 0;
+            this._targetIndex = 0;
         };
         GPUParticleSystem.prototype._createUpdateVAO = function (source) {
             var updateVertexBuffers = {};
@@ -51959,10 +51971,10 @@ var BABYLON;
                 data.push(0.0);
             }
             // Sprite data
-            var spriteData = new Float32Array([1, 1, 1, 1,
-                -1, 1, 0, 1,
-                -1, -1, 0, 0,
-                1, -1, 1, 0]);
+            var spriteData = new Float32Array([0.5, 0.5, 1, 1,
+                -0.5, 0.5, 0, 1,
+                -0.5, -0.5, 0, 0,
+                0.5, -0.5, 1, 0]);
             // Buffers
             this._buffer0 = new BABYLON.Buffer(engine, data, false, this._attributesStrideSize);
             this._buffer1 = new BABYLON.Buffer(engine, data, false, this._attributesStrideSize);
@@ -51986,10 +51998,27 @@ var BABYLON;
             this._updateEffect = new BABYLON.Effect("gpuUpdateParticles", this._updateEffectOptions, this._scene.getEngine());
         };
         /**
+         * Animates the particle system for the current frame by emitting new particles and or animating the living ones.
+         */
+        GPUParticleSystem.prototype.animate = function () {
+            if (!this._stopped) {
+                this._timeDelta = this.updateSpeed * this._scene.getAnimationRatio();
+                this._actualFrame += this._timeDelta;
+                if (this.targetStopDuration && this._actualFrame >= this.targetStopDuration)
+                    this.stop();
+            }
+            else {
+                this._timeDelta = 0;
+            }
+        };
+        /**
          * Renders the particle system in its current state.
          * @returns the current number of particles
          */
         GPUParticleSystem.prototype.render = function () {
+            if (!this._started) {
+                return 0;
+            }
             if (this.particleEmitterType) {
                 this._recreateUpdateEffect(this.particleEmitterType.getEffectDefines());
             }
@@ -52074,14 +52103,7 @@ var BABYLON;
         GPUParticleSystem.prototype.rebuild = function () {
             this._initialize(true);
         };
-        /**
-         * Disposes the particle system and free the associated resources.
-         */
-        GPUParticleSystem.prototype.dispose = function () {
-            var index = this._scene.particleSystems.indexOf(this);
-            if (index > -1) {
-                this._scene.particleSystems.splice(index, 1);
-            }
+        GPUParticleSystem.prototype._releaseBuffers = function () {
             if (this._buffer0) {
                 this._buffer0.dispose();
                 this._buffer0 = null;
@@ -52090,6 +52112,12 @@ var BABYLON;
                 this._buffer1.dispose();
                 this._buffer1 = null;
             }
+            if (this._spriteBuffer) {
+                this._spriteBuffer.dispose();
+                this._spriteBuffer = null;
+            }
+        };
+        GPUParticleSystem.prototype._releaseVAOs = function () {
             for (var index = 0; index < this._updateVAO.length; index++) {
                 this._engine.releaseVertexArrayObject(this._updateVAO[index]);
             }
@@ -52098,6 +52126,17 @@ var BABYLON;
                 this._engine.releaseVertexArrayObject(this._renderVAO[index]);
             }
             this._renderVAO = [];
+        };
+        /**
+         * Disposes the particle system and free the associated resources.
+         */
+        GPUParticleSystem.prototype.dispose = function () {
+            var index = this._scene.particleSystems.indexOf(this);
+            if (index > -1) {
+                this._scene.particleSystems.splice(index, 1);
+            }
+            this._releaseBuffers();
+            this._releaseVAOs();
             if (this._randomTexture) {
                 this._randomTexture.dispose();
                 this._randomTexture = null;
@@ -52121,6 +52160,43 @@ var BABYLON;
          * @returns the JSON object
          */
         GPUParticleSystem.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.name = this.name;
+            serializationObject.id = this.id;
+            // Emitter
+            if (this.emitter.position) {
+                var emitterMesh = this.emitter;
+                serializationObject.emitterId = emitterMesh.id;
+            }
+            else {
+                var emitterPosition = this.emitter;
+                serializationObject.emitter = emitterPosition.asArray();
+            }
+            serializationObject.capacity = this.getCapacity();
+            if (this.particleTexture) {
+                serializationObject.textureName = this.particleTexture.name;
+            }
+            // Animations
+            BABYLON.Animation.AppendSerializedAnimations(this, serializationObject);
+            // Particle system
+            serializationObject.activeParticleCount = this.activeParticleCount;
+            serializationObject.randomTextureSize = this._randomTextureSize;
+            serializationObject.minSize = this.minSize;
+            serializationObject.maxSize = this.maxSize;
+            serializationObject.minEmitPower = this.minEmitPower;
+            serializationObject.maxEmitPower = this.maxEmitPower;
+            serializationObject.minLifeTime = this.minLifeTime;
+            serializationObject.maxLifeTime = this.maxLifeTime;
+            serializationObject.emitRate = this.emitRate;
+            serializationObject.gravity = this.gravity.asArray();
+            serializationObject.color1 = this.color1.asArray();
+            serializationObject.color2 = this.color2.asArray();
+            serializationObject.colorDead = this.colorDead.asArray();
+            serializationObject.updateSpeed = this.updateSpeed;
+            serializationObject.targetStopDuration = this.targetStopDuration;
+            serializationObject.blendMode = this.blendMode;
+            // Emitters
+            return serializationObject;
         };
         return GPUParticleSystem;
     }());

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


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


+ 12 - 0
src/Particles/EmitterTypes/babylon.IParticleEmitterType.ts

@@ -38,5 +38,17 @@ module BABYLON {
          * @returns the effect defines string
          */
         getEffectDefines(): string;
+
+        /**
+         * Returns a string representing the class name
+         * @returns a string containing the class name
+         */
+        getClassName(): string;
+
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */        
+        serialize(): any;
     }
 }

+ 18 - 0
src/Particles/EmitterTypes/babylon.boxParticleEmitter.ts

@@ -90,5 +90,23 @@ module BABYLON {
         public getEffectDefines(): string {
             return "#define BOXEMITTER"
         }
+
+        /**
+         * Returns the string "BoxEmitter"
+         * @returns a string containing the class name
+         */
+        public getClassName(): string {
+            return "BoxEmitter";
+        }   
+        
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */        
+        public serialize(): any {
+            var serializationObject: any = {};
+
+            return serializationObject;
+        }
     }
 }

+ 18 - 0
src/Particles/EmitterTypes/babylon.coneParticleEmitter.ts

@@ -122,6 +122,24 @@ module BABYLON {
          */
         public getEffectDefines(): string {
             return "#define CONEEMITTER"
+        }     
+        
+        /**
+         * Returns the string "BoxEmitter"
+         * @returns a string containing the class name
+         */
+        public getClassName(): string {
+            return "ConeEmitter";
+        }  
+        
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */        
+        public serialize(): any {
+            var serializationObject: any = {};
+
+            return serializationObject;
         }        
     }
 }

+ 37 - 1
src/Particles/EmitterTypes/babylon.sphereParticleEmitter.ts

@@ -84,6 +84,24 @@ module BABYLON {
          */
         public getEffectDefines(): string {
             return "#define SPHEREEMITTER"
+        }   
+        
+        /**
+         * Returns the string "SphereParticleEmitter"
+         * @returns a string containing the class name
+         */
+        public getClassName(): string {
+            return "SphereParticleEmitter";
+        }         
+        
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */        
+        public serialize(): any {
+            var serializationObject: any = {};
+
+            return serializationObject;
         }        
     }
 
@@ -153,6 +171,24 @@ module BABYLON {
          */
         public getEffectDefines(): string {
             return "#define SPHEREEMITTER\n#define DIRECTEDSPHEREEMITTER"
-        }          
+        }    
+        
+        /**
+         * Returns the string "SphereDirectedParticleEmitter"
+         * @returns a string containing the class name
+         */
+        public getClassName(): string {
+            return "SphereDirectedParticleEmitter";
+        }       
+        
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */        
+        public serialize(): any {
+            var serializationObject: any = {};
+
+            return serializationObject;
+        }        
     }
 }

+ 133 - 27
src/Particles/babylon.gpuParticleSystem.ts

@@ -3,7 +3,7 @@
      * This represents a GPU particle system in Babylon.
      * This os the fastest particle system in Babylon as it uses the GPU to update the individual particle data.
      */
-    export class GPUParticleSystem implements IDisposable, IParticleSystem {
+    export class GPUParticleSystem implements IDisposable, IParticleSystem, IAnimatable {
         /**
          * The id of the Particle system.
          */
@@ -50,6 +50,7 @@
 
         private _currentRenderId = -1;    
         private _started = false;    
+        private _stopped = false;    
 
         private _timeDelta = 0;
 
@@ -58,6 +59,14 @@
         private readonly _attributesStrideSize = 14;
         private _updateEffectOptions: EffectCreationOptions;
 
+        private _randomTextureSize: number;
+        private _actualFrame = 0;        
+
+        /**
+         * List of animations used by the particle system.
+         */
+        public animations: Animation[] = [];        
+
         /**
          * Gets a boolean indicating if the GPU particles can be rendered on current browser
          */
@@ -79,6 +88,11 @@
         public updateSpeed = 0.01;        
 
         /**
+         * The amount of time the particle system is running (depends of the overall update speed).
+         */
+        public targetStopDuration = 0;        
+
+        /**
          * The texture used to render each particle. (this can be a spritesheet)
          */
         public particleTexture: Nullable<Texture>;   
@@ -146,9 +160,10 @@
         public particleEmitterType: Nullable<IParticleEmitterType>;        
 
         /**
-         * Gets the maximum number of particles supported by this system
+         * Gets the maximum number of particles active at the same time.
+         * @returns The max number of active particles.
          */
-        public get capacity(): number {
+        public getCapacity(): number {
             return this._capacity;
         }
 
@@ -176,16 +191,35 @@
          */
         public start(): void {
             this._started = true;
+            this._stopped = false;
         }
 
         /**
          * Stops the particle system.
          */
         public stop(): void {
-            this._started = false;
+            this._stopped = true;
         }
 
         /**
+         * Remove all active particles
+         */
+        public reset(): void {
+            this._releaseBuffers();
+            this._releaseVAOs();   
+            this._currentActiveCount = 0;         
+            this._targetIndex = 0;
+        }      
+        
+        /**
+         * Returns the string "GPUParticleSystem"
+         * @returns a string containing the class name 
+         */
+        public getClassName(): string {
+            return "GPUParticleSystem";
+        }            
+
+        /**
          * 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
@@ -244,13 +278,8 @@
             this._randomTexture = new RawTexture(new Float32Array(d), maxTextureSize, 1, Engine.TEXTUREFORMAT_RGBA32F, this._scene, false, false, Texture.NEAREST_SAMPLINGMODE, Engine.TEXTURETYPE_FLOAT)
             this._randomTexture.wrapU = Texture.WRAP_ADDRESSMODE;
             this._randomTexture.wrapV = Texture.WRAP_ADDRESSMODE;
-        }
 
-        /**
-         * Animates the particle system for the current frame by emitting new particles and or animating the living ones.
-         */
-        public animate(): void {
-            this._timeDelta = this.updateSpeed * this._scene.getAnimationRatio();               
+            this._randomTextureSize = maxTextureSize;
         }
 
         private _createUpdateVAO(source: Buffer): WebGLVertexArrayObject {            
@@ -322,10 +351,10 @@
             }
 
             // Sprite data
-            var spriteData = new Float32Array([1, 1,  1, 1,  
-                                              -1, 1,  0, 1,
-                                             -1, -1,  0, 0,   
-                                              1, -1,  1, 0]);
+            var spriteData = new Float32Array([0.5, 0.5,  1, 1,  
+                                              -0.5, 0.5,  0, 1,
+                                             -0.5, -0.5,  0, 0,   
+                                             0.5, -0.5,  1, 0]);
 
             // Buffers
             this._buffer0 = new Buffer(engine, data, false, this._attributesStrideSize);
@@ -356,10 +385,29 @@
         }
 
         /**
+         * Animates the particle system for the current frame by emitting new particles and or animating the living ones.
+         */
+        public animate(): void {           
+            if (!this._stopped) {
+                this._timeDelta = this.updateSpeed * this._scene.getAnimationRatio();   
+                this._actualFrame += this._timeDelta;
+
+                if (this.targetStopDuration && this._actualFrame >= this.targetStopDuration)
+                    this.stop();
+            } else {
+                this._timeDelta = 0;
+            }             
+        }        
+
+        /**
          * Renders the particle system in its current state.
          * @returns the current number of particles
          */
         public render(): number {
+            if (!this._started) {
+                return 0;
+            }
+
             if (this.particleEmitterType) {
                 this._recreateUpdateEffect(this.particleEmitterType.getEffectDefines());
             }
@@ -372,9 +420,8 @@
                 return 0;
             }
 
-            this._currentRenderId = this._scene.getRenderId();
+            this._currentRenderId = this._scene.getRenderId();      
             
-
             // Get everything ready to render
             this. _initialize();
 
@@ -464,15 +511,7 @@
             this._initialize(true);
         }
 
-        /**
-         * Disposes the particle system and free the associated resources.
-         */
-        public dispose(): void {
-            var index = this._scene.particleSystems.indexOf(this);
-            if (index > -1) {
-                this._scene.particleSystems.splice(index, 1);
-            }
-
+        private _releaseBuffers() {
             if (this._buffer0) {
                 this._buffer0.dispose();
                 (<any>this._buffer0) = null;
@@ -481,7 +520,13 @@
                 this._buffer1.dispose();
                 (<any>this._buffer1) = null;
             }
-            
+            if (this._spriteBuffer) {
+                this._spriteBuffer.dispose();
+                (<any>this._spriteBuffer) = null;
+            }            
+        }
+
+        private _releaseVAOs() {
             for (var index = 0; index < this._updateVAO.length; index++) {
                 this._engine.releaseVertexArrayObject(this._updateVAO[index]);
             }
@@ -490,7 +535,21 @@
             for (var index = 0; index < this._renderVAO.length; index++) {
                 this._engine.releaseVertexArrayObject(this._renderVAO[index]);
             }
-            this._renderVAO = [];            
+            this._renderVAO = [];   
+        }
+
+        /**
+         * Disposes the particle system and free the associated resources.
+         */
+        public dispose(): void {
+            var index = this._scene.particleSystems.indexOf(this);
+            if (index > -1) {
+                this._scene.particleSystems.splice(index, 1);
+            }
+
+            this._releaseBuffers();
+            this._releaseVAOs();
+         
 
             if (this._randomTexture) {
                 this._randomTexture.dispose();
@@ -519,6 +578,53 @@
          * @returns the JSON object
          */
         public serialize(): any {
+            var serializationObject: any = {};
+
+            serializationObject.name = this.name;
+            serializationObject.id = this.id;
+
+            // Emitter
+            if ((<AbstractMesh>this.emitter).position) {
+                var emitterMesh = (<AbstractMesh>this.emitter);
+                serializationObject.emitterId = emitterMesh.id;
+            } else {
+                var emitterPosition = (<Vector3>this.emitter);
+                serializationObject.emitter = emitterPosition.asArray();
+            }
+
+            serializationObject.capacity = this.getCapacity();
+
+            if (this.particleTexture) {
+                serializationObject.textureName = this.particleTexture.name;
+            }
+
+            // Animations
+            Animation.AppendSerializedAnimations(this, serializationObject);
+
+            // Particle system
+            serializationObject.activeParticleCount = this.activeParticleCount;
+            serializationObject.randomTextureSize = this._randomTextureSize;
+            serializationObject.minSize = this.minSize;
+            serializationObject.maxSize = this.maxSize;
+            serializationObject.minEmitPower = this.minEmitPower;
+            serializationObject.maxEmitPower = this.maxEmitPower;
+            serializationObject.minLifeTime = this.minLifeTime;
+            serializationObject.maxLifeTime = this.maxLifeTime;
+            serializationObject.emitRate = this.emitRate;
+            serializationObject.gravity = this.gravity.asArray();
+            serializationObject.color1 = this.color1.asArray();
+            serializationObject.color2 = this.color2.asArray();
+            serializationObject.colorDead = this.colorDead.asArray();
+            serializationObject.updateSpeed = this.updateSpeed;
+            serializationObject.targetStopDuration = this.targetStopDuration;
+            serializationObject.blendMode = this.blendMode;
+
+            // Emitters
+            if (this.particleEmitterType) {
+                
+            }
+
+            return serializationObject;            
         }
     }
 }

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

@@ -118,7 +118,7 @@
         public updateSpeed = 0.01;
 
         /**
-         * The amount of time the particle system is running (depends of the overall speed above).
+         * The amount of time the particle system is running (depends of the overall update speed).
          */
         public targetStopDuration = 0;
 
@@ -395,6 +395,14 @@
         private _isAnimationSheetEnabled: boolean;
 
         /**
+         * Returns the string "ParticleSystem"
+         * @returns a string containing the class name
+         */
+        public getClassName(): string {
+            return "ParticleSystem";
+        }        
+
+        /**
          * Instantiates a 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