David Catuhe 7 éve
szülő
commit
6361bbf524

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 8014 - 7921
Playground/babylon.d.txt


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 10459 - 10401
dist/preview release/babylon.d.ts


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 8 - 8
dist/preview release/babylon.js


+ 241 - 12
dist/preview release/babylon.max.js

@@ -50759,6 +50759,13 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+         * Returns the string "ParticleSystem"
+         * @returns a string containing the class name
+         */
+        ParticleSystem.prototype.getClassName = function () {
+            return "ParticleSystem";
+        };
         ParticleSystem.prototype._createIndexBuffer = function () {
             var indices = [];
             var index = 0;
@@ -51252,6 +51259,10 @@ var BABYLON;
             serializationObject.spriteCellWidth = this.spriteCellWidth;
             serializationObject.spriteCellHeight = this.spriteCellHeight;
             serializationObject.isAnimationSheetEnabled = this._isAnimationSheetEnabled;
+            // Emitter
+            if (this.particleEmitterType) {
+                serializationObject.particleEmitterType = this.particleEmitterType.serialize();
+            }
             return serializationObject;
         };
         /**
@@ -51428,6 +51439,40 @@ var BABYLON;
         BoxParticleEmitter.prototype.getEffectDefines = function () {
             return "#define BOXEMITTER";
         };
+        /**
+         * Returns the string "BoxEmitter"
+         * @returns a string containing the class name
+         */
+        BoxParticleEmitter.prototype.getClassName = function () {
+            return "BoxEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        BoxParticleEmitter.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.direction1 = this.direction1.asArray();
+            ;
+            serializationObject.direction2 = this.direction2.asArray();
+            ;
+            serializationObject.minEmitBox = this.minEmitBox.asArray();
+            ;
+            serializationObject.maxEmitBox = this.maxEmitBox.asArray();
+            ;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        BoxParticleEmitter.prototype.parse = function (serializationObject) {
+            this.direction1.copyFrom(serializationObject.direction1);
+            this.direction2.copyFrom(serializationObject.direction2);
+            this.minEmitBox.copyFrom(serializationObject.minEmitBox);
+            this.maxEmitBox.copyFrom(serializationObject.maxEmitBox);
+        };
         return BoxParticleEmitter;
     }());
     BABYLON.BoxParticleEmitter = BoxParticleEmitter;
@@ -51445,8 +51490,8 @@ var BABYLON;
     var ConeParticleEmitter = /** @class */ (function () {
         /**
          * Creates a new instance of @see ConeParticleEmitter
-         * @param radius the radius of the emission cone
-         * @param angles the cone base angle
+         * @param radius the radius of the emission cone (1 by default)
+         * @param angles the cone base angle (PI by default)
          * @param directionRandomizer defines how much to randomize the particle direction [0-1]
          */
         function ConeParticleEmitter(radius, 
@@ -51458,6 +51503,8 @@ var BABYLON;
              * The cone base angle.
              */
             directionRandomizer) {
+            if (radius === void 0) { radius = 1; }
+            if (angle === void 0) { angle = Math.PI; }
             if (directionRandomizer === void 0) { directionRandomizer = 0; }
             this.angle = angle;
             this.directionRandomizer = directionRandomizer;
@@ -51553,6 +51600,34 @@ var BABYLON;
         ConeParticleEmitter.prototype.getEffectDefines = function () {
             return "#define CONEEMITTER";
         };
+        /**
+         * Returns the string "BoxEmitter"
+         * @returns a string containing the class name
+         */
+        ConeParticleEmitter.prototype.getClassName = function () {
+            return "ConeEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        ConeParticleEmitter.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.radius = this.radius;
+            serializationObject.angle = this.angle;
+            serializationObject.directionRandomizer = this.directionRandomizer;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        ConeParticleEmitter.prototype.parse = function (serializationObject) {
+            this.radius = serializationObject.radius;
+            this.angle = serializationObject.angle;
+            this.directionRandomizer = serializationObject.directionRandomizer;
+        };
         return ConeParticleEmitter;
     }());
     BABYLON.ConeParticleEmitter = ConeParticleEmitter;
@@ -51570,7 +51645,7 @@ var BABYLON;
     var SphereParticleEmitter = /** @class */ (function () {
         /**
          * Creates a new instance of @see SphereParticleEmitter
-         * @param radius the radius of the emission sphere
+         * @param radius the radius of the emission sphere (1 by default)
          * @param directionRandomizer defines how much to randomize the particle direction [0-1]
          */
         function SphereParticleEmitter(
@@ -51582,6 +51657,7 @@ var BABYLON;
              * How much to randomize the particle direction [0-1].
              */
             directionRandomizer) {
+            if (radius === void 0) { radius = 1; }
             if (directionRandomizer === void 0) { directionRandomizer = 0; }
             this.radius = radius;
             this.directionRandomizer = directionRandomizer;
@@ -51642,6 +51718,32 @@ var BABYLON;
         SphereParticleEmitter.prototype.getEffectDefines = function () {
             return "#define SPHEREEMITTER";
         };
+        /**
+         * Returns the string "SphereParticleEmitter"
+         * @returns a string containing the class name
+         */
+        SphereParticleEmitter.prototype.getClassName = function () {
+            return "SphereParticleEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        SphereParticleEmitter.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.radius = this.radius;
+            serializationObject.directionRandomizer = this.directionRandomizer;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        SphereParticleEmitter.prototype.parse = function (serializationObject) {
+            this.radius = serializationObject.radius;
+            this.directionRandomizer = serializationObject.directionRandomizer;
+        };
         return SphereParticleEmitter;
     }());
     BABYLON.SphereParticleEmitter = SphereParticleEmitter;
@@ -51653,9 +51755,9 @@ var BABYLON;
         __extends(SphereDirectedParticleEmitter, _super);
         /**
          * Creates a new instance of @see SphereDirectedParticleEmitter
-         * @param radius the radius of the emission sphere
-         * @param direction1 the min limit of the emission direction
-         * @param direction2 the max limit of the emission direction
+         * @param radius the radius of the emission sphere (1 by default)
+         * @param direction1 the min limit of the emission direction (up vector by default)
+         * @param direction2 the max limit of the emission direction (up vector by default)
          */
         function SphereDirectedParticleEmitter(radius, 
             /**
@@ -51666,6 +51768,9 @@ var BABYLON;
              * The max limit of the emission direction.
              */
             direction2) {
+            if (radius === void 0) { radius = 1; }
+            if (direction1 === void 0) { direction1 = new BABYLON.Vector3(0, 1, 0); }
+            if (direction2 === void 0) { direction2 = new BABYLON.Vector3(0, 1, 0); }
             var _this = _super.call(this, radius) || this;
             _this.direction1 = direction1;
             _this.direction2 = direction2;
@@ -51709,6 +51814,35 @@ var BABYLON;
         SphereDirectedParticleEmitter.prototype.getEffectDefines = function () {
             return "#define SPHEREEMITTER\n#define DIRECTEDSPHEREEMITTER";
         };
+        /**
+         * Returns the string "SphereDirectedParticleEmitter"
+         * @returns a string containing the class name
+         */
+        SphereDirectedParticleEmitter.prototype.getClassName = function () {
+            return "SphereDirectedParticleEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        SphereDirectedParticleEmitter.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            ;
+            serializationObject.direction1 = this.direction1.asArray();
+            ;
+            serializationObject.direction2 = this.direction2.asArray();
+            ;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        SphereDirectedParticleEmitter.prototype.parse = function (serializationObject) {
+            _super.prototype.parse.call(this, serializationObject);
+            this.direction1.copyFrom(serializationObject.direction1);
+            this.direction2.copyFrom(serializationObject.direction2);
+        };
         return SphereDirectedParticleEmitter;
     }(SphereParticleEmitter));
     BABYLON.SphereDirectedParticleEmitter = SphereDirectedParticleEmitter;
@@ -51754,7 +51888,7 @@ var BABYLON;
             /**
              * The layer mask we are rendering the particles through.
              */
-            this.layerMask = 0x0FFFFFFF; // TODO
+            this.layerMask = 0x0FFFFFFF;
             this._updateVAO = new Array();
             this._renderVAO = new Array();
             this._targetIndex = 0;
@@ -51929,6 +52063,13 @@ var BABYLON;
             this._currentActiveCount = 0;
             this._targetIndex = 0;
         };
+        /**
+         * Returns the string "GPUParticleSystem"
+         * @returns a string containing the class name
+         */
+        GPUParticleSystem.prototype.getClassName = function () {
+            return "GPUParticleSystem";
+        };
         GPUParticleSystem.prototype._createUpdateVAO = function (source) {
             var updateVertexBuffers = {};
             updateVertexBuffers["position"] = source.createVertexBuffer("position", 0, 3);
@@ -52159,7 +52300,6 @@ var BABYLON;
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
         };
-        //TODO: Clone / Parse / serialize
         /**
          * Clones the particle system.
          * @param name The name of the cloned object
@@ -52167,7 +52307,16 @@ var BABYLON;
          * @returns the cloned particle system
          */
         GPUParticleSystem.prototype.clone = function (name, newEmitter) {
-            return null;
+            var result = new GPUParticleSystem(name, { capacity: this._capacity, randomTextureSize: this._randomTextureSize }, this._scene);
+            BABYLON.Tools.DeepCopy(this, result);
+            if (newEmitter === undefined) {
+                newEmitter = this.emitter;
+            }
+            result.emitter = newEmitter;
+            if (this.particleTexture) {
+                result.particleTexture = new BABYLON.Texture(this.particleTexture.url, this._scene);
+            }
+            return result;
         };
         /**
          * Serializes the particle system to a JSON object.
@@ -52209,9 +52358,83 @@ var BABYLON;
             serializationObject.updateSpeed = this.updateSpeed;
             serializationObject.targetStopDuration = this.targetStopDuration;
             serializationObject.blendMode = this.blendMode;
-            // Emitters
+            // Emitter
+            if (this.particleEmitterType) {
+                serializationObject.particleEmitterType = this.particleEmitterType.serialize();
+            }
             return serializationObject;
         };
+        /**
+         * Parses a JSON object to create a GPU particle system.
+         * @param parsedParticleSystem The JSON object to parse
+         * @param scene The scene to create the particle system in
+         * @param rootUrl The root url to use to load external dependencies like texture
+         * @returns the parsed GPU particle system
+         */
+        GPUParticleSystem.Parse = function (parsedParticleSystem, scene, rootUrl) {
+            var name = parsedParticleSystem.name;
+            var particleSystem = new GPUParticleSystem(name, { capacity: parsedParticleSystem.capacity, randomTextureSize: parsedParticleSystem.randomTextureSize }, scene);
+            if (parsedParticleSystem.id) {
+                particleSystem.id = parsedParticleSystem.id;
+            }
+            // Texture
+            if (parsedParticleSystem.textureName) {
+                particleSystem.particleTexture = new BABYLON.Texture(rootUrl + parsedParticleSystem.textureName, scene);
+                particleSystem.particleTexture.name = parsedParticleSystem.textureName;
+            }
+            // Emitter
+            if (parsedParticleSystem.emitterId) {
+                particleSystem.emitter = scene.getLastMeshByID(parsedParticleSystem.emitterId);
+            }
+            else {
+                particleSystem.emitter = BABYLON.Vector3.FromArray(parsedParticleSystem.emitter);
+            }
+            // Animations
+            if (parsedParticleSystem.animations) {
+                for (var animationIndex = 0; animationIndex < parsedParticleSystem.animations.length; animationIndex++) {
+                    var parsedAnimation = parsedParticleSystem.animations[animationIndex];
+                    particleSystem.animations.push(BABYLON.Animation.Parse(parsedAnimation));
+                }
+            }
+            // Particle system
+            particleSystem.activeParticleCount = parsedParticleSystem.activeParticleCount;
+            particleSystem.minSize = parsedParticleSystem.minSize;
+            particleSystem.maxSize = parsedParticleSystem.maxSize;
+            particleSystem.minLifeTime = parsedParticleSystem.minLifeTime;
+            particleSystem.maxLifeTime = parsedParticleSystem.maxLifeTime;
+            particleSystem.minEmitPower = parsedParticleSystem.minEmitPower;
+            particleSystem.maxEmitPower = parsedParticleSystem.maxEmitPower;
+            particleSystem.emitRate = parsedParticleSystem.emitRate;
+            particleSystem.gravity = BABYLON.Vector3.FromArray(parsedParticleSystem.gravity);
+            particleSystem.color1 = BABYLON.Color4.FromArray(parsedParticleSystem.color1);
+            particleSystem.color2 = BABYLON.Color4.FromArray(parsedParticleSystem.color2);
+            particleSystem.colorDead = BABYLON.Color4.FromArray(parsedParticleSystem.colorDead);
+            particleSystem.updateSpeed = parsedParticleSystem.updateSpeed;
+            particleSystem.targetStopDuration = parsedParticleSystem.targetStopDuration;
+            particleSystem.blendMode = parsedParticleSystem.blendMode;
+            // Emitter
+            if (parsedParticleSystem.particleEmitterType) {
+                var emitterType = void 0;
+                switch (parsedParticleSystem.particleEmitterType.type) {
+                    case "SphereEmitter":
+                        emitterType = new BABYLON.SphereParticleEmitter();
+                        break;
+                    case "SphereDirectedParticleEmitter":
+                        emitterType = new BABYLON.SphereDirectedParticleEmitter();
+                        break;
+                    case "ConeEmitter":
+                        emitterType = new BABYLON.ConeParticleEmitter();
+                        break;
+                    case "BoxEmitter":
+                    default:
+                        emitterType = new BABYLON.BoxParticleEmitter();
+                        break;
+                }
+                emitterType.parse(parsedParticleSystem.particleEmitterType);
+                particleSystem.particleEmitterType = emitterType;
+            }
+            return particleSystem;
+        };
         return GPUParticleSystem;
     }());
     BABYLON.GPUParticleSystem = GPUParticleSystem;
@@ -61392,8 +61615,14 @@ var BABYLON;
             if (parsedData.particleSystems !== undefined && parsedData.particleSystems !== null) {
                 for (index = 0, cache = parsedData.particleSystems.length; index < cache; index++) {
                     var parsedParticleSystem = parsedData.particleSystems[index];
-                    var ps = BABYLON.ParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
-                    container.particleSystems.push(ps);
+                    if (parsedParticleSystem.activeParticleCount) {
+                        var ps = BABYLON.GPUParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
+                        container.particleSystems.push(ps);
+                    }
+                    else {
+                        var ps = BABYLON.ParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
+                        container.particleSystems.push(ps);
+                    }
                 }
             }
             // Lens flares

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 8 - 8
dist/preview release/babylon.worker.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 1439 - 1346
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 21 - 21
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 2869 - 2718
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 2869 - 2718
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


+ 241 - 12
dist/preview release/es6.js

@@ -50745,6 +50745,13 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+         * Returns the string "ParticleSystem"
+         * @returns a string containing the class name
+         */
+        ParticleSystem.prototype.getClassName = function () {
+            return "ParticleSystem";
+        };
         ParticleSystem.prototype._createIndexBuffer = function () {
             var indices = [];
             var index = 0;
@@ -51238,6 +51245,10 @@ var BABYLON;
             serializationObject.spriteCellWidth = this.spriteCellWidth;
             serializationObject.spriteCellHeight = this.spriteCellHeight;
             serializationObject.isAnimationSheetEnabled = this._isAnimationSheetEnabled;
+            // Emitter
+            if (this.particleEmitterType) {
+                serializationObject.particleEmitterType = this.particleEmitterType.serialize();
+            }
             return serializationObject;
         };
         /**
@@ -51414,6 +51425,40 @@ var BABYLON;
         BoxParticleEmitter.prototype.getEffectDefines = function () {
             return "#define BOXEMITTER";
         };
+        /**
+         * Returns the string "BoxEmitter"
+         * @returns a string containing the class name
+         */
+        BoxParticleEmitter.prototype.getClassName = function () {
+            return "BoxEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        BoxParticleEmitter.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.direction1 = this.direction1.asArray();
+            ;
+            serializationObject.direction2 = this.direction2.asArray();
+            ;
+            serializationObject.minEmitBox = this.minEmitBox.asArray();
+            ;
+            serializationObject.maxEmitBox = this.maxEmitBox.asArray();
+            ;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        BoxParticleEmitter.prototype.parse = function (serializationObject) {
+            this.direction1.copyFrom(serializationObject.direction1);
+            this.direction2.copyFrom(serializationObject.direction2);
+            this.minEmitBox.copyFrom(serializationObject.minEmitBox);
+            this.maxEmitBox.copyFrom(serializationObject.maxEmitBox);
+        };
         return BoxParticleEmitter;
     }());
     BABYLON.BoxParticleEmitter = BoxParticleEmitter;
@@ -51431,8 +51476,8 @@ var BABYLON;
     var ConeParticleEmitter = /** @class */ (function () {
         /**
          * Creates a new instance of @see ConeParticleEmitter
-         * @param radius the radius of the emission cone
-         * @param angles the cone base angle
+         * @param radius the radius of the emission cone (1 by default)
+         * @param angles the cone base angle (PI by default)
          * @param directionRandomizer defines how much to randomize the particle direction [0-1]
          */
         function ConeParticleEmitter(radius, 
@@ -51444,6 +51489,8 @@ var BABYLON;
              * The cone base angle.
              */
             directionRandomizer) {
+            if (radius === void 0) { radius = 1; }
+            if (angle === void 0) { angle = Math.PI; }
             if (directionRandomizer === void 0) { directionRandomizer = 0; }
             this.angle = angle;
             this.directionRandomizer = directionRandomizer;
@@ -51539,6 +51586,34 @@ var BABYLON;
         ConeParticleEmitter.prototype.getEffectDefines = function () {
             return "#define CONEEMITTER";
         };
+        /**
+         * Returns the string "BoxEmitter"
+         * @returns a string containing the class name
+         */
+        ConeParticleEmitter.prototype.getClassName = function () {
+            return "ConeEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        ConeParticleEmitter.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.radius = this.radius;
+            serializationObject.angle = this.angle;
+            serializationObject.directionRandomizer = this.directionRandomizer;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        ConeParticleEmitter.prototype.parse = function (serializationObject) {
+            this.radius = serializationObject.radius;
+            this.angle = serializationObject.angle;
+            this.directionRandomizer = serializationObject.directionRandomizer;
+        };
         return ConeParticleEmitter;
     }());
     BABYLON.ConeParticleEmitter = ConeParticleEmitter;
@@ -51556,7 +51631,7 @@ var BABYLON;
     var SphereParticleEmitter = /** @class */ (function () {
         /**
          * Creates a new instance of @see SphereParticleEmitter
-         * @param radius the radius of the emission sphere
+         * @param radius the radius of the emission sphere (1 by default)
          * @param directionRandomizer defines how much to randomize the particle direction [0-1]
          */
         function SphereParticleEmitter(
@@ -51568,6 +51643,7 @@ var BABYLON;
              * How much to randomize the particle direction [0-1].
              */
             directionRandomizer) {
+            if (radius === void 0) { radius = 1; }
             if (directionRandomizer === void 0) { directionRandomizer = 0; }
             this.radius = radius;
             this.directionRandomizer = directionRandomizer;
@@ -51628,6 +51704,32 @@ var BABYLON;
         SphereParticleEmitter.prototype.getEffectDefines = function () {
             return "#define SPHEREEMITTER";
         };
+        /**
+         * Returns the string "SphereParticleEmitter"
+         * @returns a string containing the class name
+         */
+        SphereParticleEmitter.prototype.getClassName = function () {
+            return "SphereParticleEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        SphereParticleEmitter.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.radius = this.radius;
+            serializationObject.directionRandomizer = this.directionRandomizer;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        SphereParticleEmitter.prototype.parse = function (serializationObject) {
+            this.radius = serializationObject.radius;
+            this.directionRandomizer = serializationObject.directionRandomizer;
+        };
         return SphereParticleEmitter;
     }());
     BABYLON.SphereParticleEmitter = SphereParticleEmitter;
@@ -51639,9 +51741,9 @@ var BABYLON;
         __extends(SphereDirectedParticleEmitter, _super);
         /**
          * Creates a new instance of @see SphereDirectedParticleEmitter
-         * @param radius the radius of the emission sphere
-         * @param direction1 the min limit of the emission direction
-         * @param direction2 the max limit of the emission direction
+         * @param radius the radius of the emission sphere (1 by default)
+         * @param direction1 the min limit of the emission direction (up vector by default)
+         * @param direction2 the max limit of the emission direction (up vector by default)
          */
         function SphereDirectedParticleEmitter(radius, 
             /**
@@ -51652,6 +51754,9 @@ var BABYLON;
              * The max limit of the emission direction.
              */
             direction2) {
+            if (radius === void 0) { radius = 1; }
+            if (direction1 === void 0) { direction1 = new BABYLON.Vector3(0, 1, 0); }
+            if (direction2 === void 0) { direction2 = new BABYLON.Vector3(0, 1, 0); }
             var _this = _super.call(this, radius) || this;
             _this.direction1 = direction1;
             _this.direction2 = direction2;
@@ -51695,6 +51800,35 @@ var BABYLON;
         SphereDirectedParticleEmitter.prototype.getEffectDefines = function () {
             return "#define SPHEREEMITTER\n#define DIRECTEDSPHEREEMITTER";
         };
+        /**
+         * Returns the string "SphereDirectedParticleEmitter"
+         * @returns a string containing the class name
+         */
+        SphereDirectedParticleEmitter.prototype.getClassName = function () {
+            return "SphereDirectedParticleEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        SphereDirectedParticleEmitter.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            ;
+            serializationObject.direction1 = this.direction1.asArray();
+            ;
+            serializationObject.direction2 = this.direction2.asArray();
+            ;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        SphereDirectedParticleEmitter.prototype.parse = function (serializationObject) {
+            _super.prototype.parse.call(this, serializationObject);
+            this.direction1.copyFrom(serializationObject.direction1);
+            this.direction2.copyFrom(serializationObject.direction2);
+        };
         return SphereDirectedParticleEmitter;
     }(SphereParticleEmitter));
     BABYLON.SphereDirectedParticleEmitter = SphereDirectedParticleEmitter;
@@ -51740,7 +51874,7 @@ var BABYLON;
             /**
              * The layer mask we are rendering the particles through.
              */
-            this.layerMask = 0x0FFFFFFF; // TODO
+            this.layerMask = 0x0FFFFFFF;
             this._updateVAO = new Array();
             this._renderVAO = new Array();
             this._targetIndex = 0;
@@ -51915,6 +52049,13 @@ var BABYLON;
             this._currentActiveCount = 0;
             this._targetIndex = 0;
         };
+        /**
+         * Returns the string "GPUParticleSystem"
+         * @returns a string containing the class name
+         */
+        GPUParticleSystem.prototype.getClassName = function () {
+            return "GPUParticleSystem";
+        };
         GPUParticleSystem.prototype._createUpdateVAO = function (source) {
             var updateVertexBuffers = {};
             updateVertexBuffers["position"] = source.createVertexBuffer("position", 0, 3);
@@ -52145,7 +52286,6 @@ var BABYLON;
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
         };
-        //TODO: Clone / Parse / serialize
         /**
          * Clones the particle system.
          * @param name The name of the cloned object
@@ -52153,7 +52293,16 @@ var BABYLON;
          * @returns the cloned particle system
          */
         GPUParticleSystem.prototype.clone = function (name, newEmitter) {
-            return null;
+            var result = new GPUParticleSystem(name, { capacity: this._capacity, randomTextureSize: this._randomTextureSize }, this._scene);
+            BABYLON.Tools.DeepCopy(this, result);
+            if (newEmitter === undefined) {
+                newEmitter = this.emitter;
+            }
+            result.emitter = newEmitter;
+            if (this.particleTexture) {
+                result.particleTexture = new BABYLON.Texture(this.particleTexture.url, this._scene);
+            }
+            return result;
         };
         /**
          * Serializes the particle system to a JSON object.
@@ -52195,9 +52344,83 @@ var BABYLON;
             serializationObject.updateSpeed = this.updateSpeed;
             serializationObject.targetStopDuration = this.targetStopDuration;
             serializationObject.blendMode = this.blendMode;
-            // Emitters
+            // Emitter
+            if (this.particleEmitterType) {
+                serializationObject.particleEmitterType = this.particleEmitterType.serialize();
+            }
             return serializationObject;
         };
+        /**
+         * Parses a JSON object to create a GPU particle system.
+         * @param parsedParticleSystem The JSON object to parse
+         * @param scene The scene to create the particle system in
+         * @param rootUrl The root url to use to load external dependencies like texture
+         * @returns the parsed GPU particle system
+         */
+        GPUParticleSystem.Parse = function (parsedParticleSystem, scene, rootUrl) {
+            var name = parsedParticleSystem.name;
+            var particleSystem = new GPUParticleSystem(name, { capacity: parsedParticleSystem.capacity, randomTextureSize: parsedParticleSystem.randomTextureSize }, scene);
+            if (parsedParticleSystem.id) {
+                particleSystem.id = parsedParticleSystem.id;
+            }
+            // Texture
+            if (parsedParticleSystem.textureName) {
+                particleSystem.particleTexture = new BABYLON.Texture(rootUrl + parsedParticleSystem.textureName, scene);
+                particleSystem.particleTexture.name = parsedParticleSystem.textureName;
+            }
+            // Emitter
+            if (parsedParticleSystem.emitterId) {
+                particleSystem.emitter = scene.getLastMeshByID(parsedParticleSystem.emitterId);
+            }
+            else {
+                particleSystem.emitter = BABYLON.Vector3.FromArray(parsedParticleSystem.emitter);
+            }
+            // Animations
+            if (parsedParticleSystem.animations) {
+                for (var animationIndex = 0; animationIndex < parsedParticleSystem.animations.length; animationIndex++) {
+                    var parsedAnimation = parsedParticleSystem.animations[animationIndex];
+                    particleSystem.animations.push(BABYLON.Animation.Parse(parsedAnimation));
+                }
+            }
+            // Particle system
+            particleSystem.activeParticleCount = parsedParticleSystem.activeParticleCount;
+            particleSystem.minSize = parsedParticleSystem.minSize;
+            particleSystem.maxSize = parsedParticleSystem.maxSize;
+            particleSystem.minLifeTime = parsedParticleSystem.minLifeTime;
+            particleSystem.maxLifeTime = parsedParticleSystem.maxLifeTime;
+            particleSystem.minEmitPower = parsedParticleSystem.minEmitPower;
+            particleSystem.maxEmitPower = parsedParticleSystem.maxEmitPower;
+            particleSystem.emitRate = parsedParticleSystem.emitRate;
+            particleSystem.gravity = BABYLON.Vector3.FromArray(parsedParticleSystem.gravity);
+            particleSystem.color1 = BABYLON.Color4.FromArray(parsedParticleSystem.color1);
+            particleSystem.color2 = BABYLON.Color4.FromArray(parsedParticleSystem.color2);
+            particleSystem.colorDead = BABYLON.Color4.FromArray(parsedParticleSystem.colorDead);
+            particleSystem.updateSpeed = parsedParticleSystem.updateSpeed;
+            particleSystem.targetStopDuration = parsedParticleSystem.targetStopDuration;
+            particleSystem.blendMode = parsedParticleSystem.blendMode;
+            // Emitter
+            if (parsedParticleSystem.particleEmitterType) {
+                var emitterType = void 0;
+                switch (parsedParticleSystem.particleEmitterType.type) {
+                    case "SphereEmitter":
+                        emitterType = new BABYLON.SphereParticleEmitter();
+                        break;
+                    case "SphereDirectedParticleEmitter":
+                        emitterType = new BABYLON.SphereDirectedParticleEmitter();
+                        break;
+                    case "ConeEmitter":
+                        emitterType = new BABYLON.ConeParticleEmitter();
+                        break;
+                    case "BoxEmitter":
+                    default:
+                        emitterType = new BABYLON.BoxParticleEmitter();
+                        break;
+                }
+                emitterType.parse(parsedParticleSystem.particleEmitterType);
+                particleSystem.particleEmitterType = emitterType;
+            }
+            return particleSystem;
+        };
         return GPUParticleSystem;
     }());
     BABYLON.GPUParticleSystem = GPUParticleSystem;
@@ -61378,8 +61601,14 @@ var BABYLON;
             if (parsedData.particleSystems !== undefined && parsedData.particleSystems !== null) {
                 for (index = 0, cache = parsedData.particleSystems.length; index < cache; index++) {
                     var parsedParticleSystem = parsedData.particleSystems[index];
-                    var ps = BABYLON.ParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
-                    container.particleSystems.push(ps);
+                    if (parsedParticleSystem.activeParticleCount) {
+                        var ps = BABYLON.GPUParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
+                        container.particleSystems.push(ps);
+                    }
+                    else {
+                        var ps = BABYLON.ParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
+                        container.particleSystems.push(ps);
+                    }
                 }
             }
             // Lens flares

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 22 - 22
dist/preview release/viewer/babylon.viewer.js


+ 241 - 12
dist/preview release/viewer/babylon.viewer.max.js

@@ -50832,6 +50832,13 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+         * Returns the string "ParticleSystem"
+         * @returns a string containing the class name
+         */
+        ParticleSystem.prototype.getClassName = function () {
+            return "ParticleSystem";
+        };
         ParticleSystem.prototype._createIndexBuffer = function () {
             var indices = [];
             var index = 0;
@@ -51325,6 +51332,10 @@ var BABYLON;
             serializationObject.spriteCellWidth = this.spriteCellWidth;
             serializationObject.spriteCellHeight = this.spriteCellHeight;
             serializationObject.isAnimationSheetEnabled = this._isAnimationSheetEnabled;
+            // Emitter
+            if (this.particleEmitterType) {
+                serializationObject.particleEmitterType = this.particleEmitterType.serialize();
+            }
             return serializationObject;
         };
         /**
@@ -51501,6 +51512,40 @@ var BABYLON;
         BoxParticleEmitter.prototype.getEffectDefines = function () {
             return "#define BOXEMITTER";
         };
+        /**
+         * Returns the string "BoxEmitter"
+         * @returns a string containing the class name
+         */
+        BoxParticleEmitter.prototype.getClassName = function () {
+            return "BoxEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        BoxParticleEmitter.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.direction1 = this.direction1.asArray();
+            ;
+            serializationObject.direction2 = this.direction2.asArray();
+            ;
+            serializationObject.minEmitBox = this.minEmitBox.asArray();
+            ;
+            serializationObject.maxEmitBox = this.maxEmitBox.asArray();
+            ;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        BoxParticleEmitter.prototype.parse = function (serializationObject) {
+            this.direction1.copyFrom(serializationObject.direction1);
+            this.direction2.copyFrom(serializationObject.direction2);
+            this.minEmitBox.copyFrom(serializationObject.minEmitBox);
+            this.maxEmitBox.copyFrom(serializationObject.maxEmitBox);
+        };
         return BoxParticleEmitter;
     }());
     BABYLON.BoxParticleEmitter = BoxParticleEmitter;
@@ -51518,8 +51563,8 @@ var BABYLON;
     var ConeParticleEmitter = /** @class */ (function () {
         /**
          * Creates a new instance of @see ConeParticleEmitter
-         * @param radius the radius of the emission cone
-         * @param angles the cone base angle
+         * @param radius the radius of the emission cone (1 by default)
+         * @param angles the cone base angle (PI by default)
          * @param directionRandomizer defines how much to randomize the particle direction [0-1]
          */
         function ConeParticleEmitter(radius, 
@@ -51531,6 +51576,8 @@ var BABYLON;
              * The cone base angle.
              */
             directionRandomizer) {
+            if (radius === void 0) { radius = 1; }
+            if (angle === void 0) { angle = Math.PI; }
             if (directionRandomizer === void 0) { directionRandomizer = 0; }
             this.angle = angle;
             this.directionRandomizer = directionRandomizer;
@@ -51626,6 +51673,34 @@ var BABYLON;
         ConeParticleEmitter.prototype.getEffectDefines = function () {
             return "#define CONEEMITTER";
         };
+        /**
+         * Returns the string "BoxEmitter"
+         * @returns a string containing the class name
+         */
+        ConeParticleEmitter.prototype.getClassName = function () {
+            return "ConeEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        ConeParticleEmitter.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.radius = this.radius;
+            serializationObject.angle = this.angle;
+            serializationObject.directionRandomizer = this.directionRandomizer;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        ConeParticleEmitter.prototype.parse = function (serializationObject) {
+            this.radius = serializationObject.radius;
+            this.angle = serializationObject.angle;
+            this.directionRandomizer = serializationObject.directionRandomizer;
+        };
         return ConeParticleEmitter;
     }());
     BABYLON.ConeParticleEmitter = ConeParticleEmitter;
@@ -51643,7 +51718,7 @@ var BABYLON;
     var SphereParticleEmitter = /** @class */ (function () {
         /**
          * Creates a new instance of @see SphereParticleEmitter
-         * @param radius the radius of the emission sphere
+         * @param radius the radius of the emission sphere (1 by default)
          * @param directionRandomizer defines how much to randomize the particle direction [0-1]
          */
         function SphereParticleEmitter(
@@ -51655,6 +51730,7 @@ var BABYLON;
              * How much to randomize the particle direction [0-1].
              */
             directionRandomizer) {
+            if (radius === void 0) { radius = 1; }
             if (directionRandomizer === void 0) { directionRandomizer = 0; }
             this.radius = radius;
             this.directionRandomizer = directionRandomizer;
@@ -51715,6 +51791,32 @@ var BABYLON;
         SphereParticleEmitter.prototype.getEffectDefines = function () {
             return "#define SPHEREEMITTER";
         };
+        /**
+         * Returns the string "SphereParticleEmitter"
+         * @returns a string containing the class name
+         */
+        SphereParticleEmitter.prototype.getClassName = function () {
+            return "SphereParticleEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        SphereParticleEmitter.prototype.serialize = function () {
+            var serializationObject = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.radius = this.radius;
+            serializationObject.directionRandomizer = this.directionRandomizer;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        SphereParticleEmitter.prototype.parse = function (serializationObject) {
+            this.radius = serializationObject.radius;
+            this.directionRandomizer = serializationObject.directionRandomizer;
+        };
         return SphereParticleEmitter;
     }());
     BABYLON.SphereParticleEmitter = SphereParticleEmitter;
@@ -51726,9 +51828,9 @@ var BABYLON;
         __extends(SphereDirectedParticleEmitter, _super);
         /**
          * Creates a new instance of @see SphereDirectedParticleEmitter
-         * @param radius the radius of the emission sphere
-         * @param direction1 the min limit of the emission direction
-         * @param direction2 the max limit of the emission direction
+         * @param radius the radius of the emission sphere (1 by default)
+         * @param direction1 the min limit of the emission direction (up vector by default)
+         * @param direction2 the max limit of the emission direction (up vector by default)
          */
         function SphereDirectedParticleEmitter(radius, 
             /**
@@ -51739,6 +51841,9 @@ var BABYLON;
              * The max limit of the emission direction.
              */
             direction2) {
+            if (radius === void 0) { radius = 1; }
+            if (direction1 === void 0) { direction1 = new BABYLON.Vector3(0, 1, 0); }
+            if (direction2 === void 0) { direction2 = new BABYLON.Vector3(0, 1, 0); }
             var _this = _super.call(this, radius) || this;
             _this.direction1 = direction1;
             _this.direction2 = direction2;
@@ -51782,6 +51887,35 @@ var BABYLON;
         SphereDirectedParticleEmitter.prototype.getEffectDefines = function () {
             return "#define SPHEREEMITTER\n#define DIRECTEDSPHEREEMITTER";
         };
+        /**
+         * Returns the string "SphereDirectedParticleEmitter"
+         * @returns a string containing the class name
+         */
+        SphereDirectedParticleEmitter.prototype.getClassName = function () {
+            return "SphereDirectedParticleEmitter";
+        };
+        /**
+         * Serializes the particle system to a JSON object.
+         * @returns the JSON object
+         */
+        SphereDirectedParticleEmitter.prototype.serialize = function () {
+            var serializationObject = _super.prototype.serialize.call(this);
+            ;
+            serializationObject.direction1 = this.direction1.asArray();
+            ;
+            serializationObject.direction2 = this.direction2.asArray();
+            ;
+            return serializationObject;
+        };
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        SphereDirectedParticleEmitter.prototype.parse = function (serializationObject) {
+            _super.prototype.parse.call(this, serializationObject);
+            this.direction1.copyFrom(serializationObject.direction1);
+            this.direction2.copyFrom(serializationObject.direction2);
+        };
         return SphereDirectedParticleEmitter;
     }(SphereParticleEmitter));
     BABYLON.SphereDirectedParticleEmitter = SphereDirectedParticleEmitter;
@@ -51827,7 +51961,7 @@ var BABYLON;
             /**
              * The layer mask we are rendering the particles through.
              */
-            this.layerMask = 0x0FFFFFFF; // TODO
+            this.layerMask = 0x0FFFFFFF;
             this._updateVAO = new Array();
             this._renderVAO = new Array();
             this._targetIndex = 0;
@@ -52002,6 +52136,13 @@ var BABYLON;
             this._currentActiveCount = 0;
             this._targetIndex = 0;
         };
+        /**
+         * Returns the string "GPUParticleSystem"
+         * @returns a string containing the class name
+         */
+        GPUParticleSystem.prototype.getClassName = function () {
+            return "GPUParticleSystem";
+        };
         GPUParticleSystem.prototype._createUpdateVAO = function (source) {
             var updateVertexBuffers = {};
             updateVertexBuffers["position"] = source.createVertexBuffer("position", 0, 3);
@@ -52232,7 +52373,6 @@ var BABYLON;
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
         };
-        //TODO: Clone / Parse / serialize
         /**
          * Clones the particle system.
          * @param name The name of the cloned object
@@ -52240,7 +52380,16 @@ var BABYLON;
          * @returns the cloned particle system
          */
         GPUParticleSystem.prototype.clone = function (name, newEmitter) {
-            return null;
+            var result = new GPUParticleSystem(name, { capacity: this._capacity, randomTextureSize: this._randomTextureSize }, this._scene);
+            BABYLON.Tools.DeepCopy(this, result);
+            if (newEmitter === undefined) {
+                newEmitter = this.emitter;
+            }
+            result.emitter = newEmitter;
+            if (this.particleTexture) {
+                result.particleTexture = new BABYLON.Texture(this.particleTexture.url, this._scene);
+            }
+            return result;
         };
         /**
          * Serializes the particle system to a JSON object.
@@ -52282,9 +52431,83 @@ var BABYLON;
             serializationObject.updateSpeed = this.updateSpeed;
             serializationObject.targetStopDuration = this.targetStopDuration;
             serializationObject.blendMode = this.blendMode;
-            // Emitters
+            // Emitter
+            if (this.particleEmitterType) {
+                serializationObject.particleEmitterType = this.particleEmitterType.serialize();
+            }
             return serializationObject;
         };
+        /**
+         * Parses a JSON object to create a GPU particle system.
+         * @param parsedParticleSystem The JSON object to parse
+         * @param scene The scene to create the particle system in
+         * @param rootUrl The root url to use to load external dependencies like texture
+         * @returns the parsed GPU particle system
+         */
+        GPUParticleSystem.Parse = function (parsedParticleSystem, scene, rootUrl) {
+            var name = parsedParticleSystem.name;
+            var particleSystem = new GPUParticleSystem(name, { capacity: parsedParticleSystem.capacity, randomTextureSize: parsedParticleSystem.randomTextureSize }, scene);
+            if (parsedParticleSystem.id) {
+                particleSystem.id = parsedParticleSystem.id;
+            }
+            // Texture
+            if (parsedParticleSystem.textureName) {
+                particleSystem.particleTexture = new BABYLON.Texture(rootUrl + parsedParticleSystem.textureName, scene);
+                particleSystem.particleTexture.name = parsedParticleSystem.textureName;
+            }
+            // Emitter
+            if (parsedParticleSystem.emitterId) {
+                particleSystem.emitter = scene.getLastMeshByID(parsedParticleSystem.emitterId);
+            }
+            else {
+                particleSystem.emitter = BABYLON.Vector3.FromArray(parsedParticleSystem.emitter);
+            }
+            // Animations
+            if (parsedParticleSystem.animations) {
+                for (var animationIndex = 0; animationIndex < parsedParticleSystem.animations.length; animationIndex++) {
+                    var parsedAnimation = parsedParticleSystem.animations[animationIndex];
+                    particleSystem.animations.push(BABYLON.Animation.Parse(parsedAnimation));
+                }
+            }
+            // Particle system
+            particleSystem.activeParticleCount = parsedParticleSystem.activeParticleCount;
+            particleSystem.minSize = parsedParticleSystem.minSize;
+            particleSystem.maxSize = parsedParticleSystem.maxSize;
+            particleSystem.minLifeTime = parsedParticleSystem.minLifeTime;
+            particleSystem.maxLifeTime = parsedParticleSystem.maxLifeTime;
+            particleSystem.minEmitPower = parsedParticleSystem.minEmitPower;
+            particleSystem.maxEmitPower = parsedParticleSystem.maxEmitPower;
+            particleSystem.emitRate = parsedParticleSystem.emitRate;
+            particleSystem.gravity = BABYLON.Vector3.FromArray(parsedParticleSystem.gravity);
+            particleSystem.color1 = BABYLON.Color4.FromArray(parsedParticleSystem.color1);
+            particleSystem.color2 = BABYLON.Color4.FromArray(parsedParticleSystem.color2);
+            particleSystem.colorDead = BABYLON.Color4.FromArray(parsedParticleSystem.colorDead);
+            particleSystem.updateSpeed = parsedParticleSystem.updateSpeed;
+            particleSystem.targetStopDuration = parsedParticleSystem.targetStopDuration;
+            particleSystem.blendMode = parsedParticleSystem.blendMode;
+            // Emitter
+            if (parsedParticleSystem.particleEmitterType) {
+                var emitterType = void 0;
+                switch (parsedParticleSystem.particleEmitterType.type) {
+                    case "SphereEmitter":
+                        emitterType = new BABYLON.SphereParticleEmitter();
+                        break;
+                    case "SphereDirectedParticleEmitter":
+                        emitterType = new BABYLON.SphereDirectedParticleEmitter();
+                        break;
+                    case "ConeEmitter":
+                        emitterType = new BABYLON.ConeParticleEmitter();
+                        break;
+                    case "BoxEmitter":
+                    default:
+                        emitterType = new BABYLON.BoxParticleEmitter();
+                        break;
+                }
+                emitterType.parse(parsedParticleSystem.particleEmitterType);
+                particleSystem.particleEmitterType = emitterType;
+            }
+            return particleSystem;
+        };
         return GPUParticleSystem;
     }());
     BABYLON.GPUParticleSystem = GPUParticleSystem;
@@ -61465,8 +61688,14 @@ var BABYLON;
             if (parsedData.particleSystems !== undefined && parsedData.particleSystems !== null) {
                 for (index = 0, cache = parsedData.particleSystems.length; index < cache; index++) {
                     var parsedParticleSystem = parsedData.particleSystems[index];
-                    var ps = BABYLON.ParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
-                    container.particleSystems.push(ps);
+                    if (parsedParticleSystem.activeParticleCount) {
+                        var ps = BABYLON.GPUParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
+                        container.particleSystems.push(ps);
+                    }
+                    else {
+                        var ps = BABYLON.ParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
+                        container.particleSystems.push(ps);
+                    }
                 }
             }
             // Lens flares

+ 8 - 2
src/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -298,8 +298,14 @@
             if (parsedData.particleSystems !== undefined && parsedData.particleSystems !== null) {
                 for (index = 0, cache = parsedData.particleSystems.length; index < cache; index++) {
                     var parsedParticleSystem = parsedData.particleSystems[index];
-                    var ps = ParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
-                    container.particleSystems.push(ps);
+
+                    if (parsedParticleSystem.activeParticleCount) {
+                        let ps = GPUParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
+                        container.particleSystems.push(ps);
+                    } else {
+                        let ps = ParticleSystem.Parse(parsedParticleSystem, scene, rootUrl);
+                        container.particleSystems.push(ps);
+                    }
                 }
             }
 

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

@@ -50,5 +50,11 @@ module BABYLON {
          * @returns the JSON object
          */        
         serialize(): any;
+
+ /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        parse(serializationObject: any): void;
     }
 }

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

@@ -106,7 +106,24 @@ module BABYLON {
         public serialize(): any {
             var serializationObject: any = {};
 
+            serializationObject.type = this.getClassName();
+            serializationObject.direction1  = this.direction1.asArray();;
+            serializationObject.direction2  = this.direction2.asArray();;
+            serializationObject.minEmitBox  = this.minEmitBox.asArray();;
+            serializationObject.maxEmitBox  = this.maxEmitBox.asArray();;
+
             return serializationObject;
         }
+
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        public parse(serializationObject: any): void {
+            this.direction1.copyFrom(serializationObject.direction1);
+            this.direction2.copyFrom(serializationObject.direction2);
+            this.minEmitBox.copyFrom(serializationObject.minEmitBox);
+            this.maxEmitBox.copyFrom(serializationObject.maxEmitBox);
+        }
     }
 }

+ 19 - 4
src/Particles/EmitterTypes/babylon.coneParticleEmitter.ts

@@ -30,15 +30,15 @@ module BABYLON {
 
         /**
          * Creates a new instance of @see ConeParticleEmitter
-         * @param radius the radius of the emission cone
-         * @param angles the cone base angle
+         * @param radius the radius of the emission cone (1 by default)
+         * @param angles the cone base angle (PI by default)
          * @param directionRandomizer defines how much to randomize the particle direction [0-1]
          */
-        constructor(radius: number, 
+        constructor(radius = 1, 
             /**
              * The radius of the emission cone.
              */
-            public angle: number, 
+            public angle = Math.PI, 
             /**
              * The cone base angle.
              */
@@ -139,7 +139,22 @@ module BABYLON {
         public serialize(): any {
             var serializationObject: any = {};
 
+            serializationObject.type = this.getClassName();
+            serializationObject.radius  = this.radius;
+            serializationObject.angle  = this.angle;
+            serializationObject.directionRandomizer  = this.directionRandomizer;
+
             return serializationObject;
+        }   
+
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        public parse(serializationObject: any): void {
+            this.radius = serializationObject.radius;
+            this.angle = serializationObject.angle;
+            this.directionRandomizer = serializationObject.directionRandomizer;
         }        
     }
 }

+ 40 - 14
src/Particles/EmitterTypes/babylon.sphereParticleEmitter.ts

@@ -7,14 +7,14 @@ module BABYLON {
 
         /**
          * Creates a new instance of @see SphereParticleEmitter
-         * @param radius the radius of the emission sphere
+         * @param radius the radius of the emission sphere (1 by default)
          * @param directionRandomizer defines how much to randomize the particle direction [0-1]
          */
         constructor(
             /**
              * The radius of the emission sphere.
              */
-            public radius: number, 
+            public radius = 1, 
             /**
              * How much to randomize the particle direction [0-1].
              */
@@ -51,9 +51,10 @@ module BABYLON {
         public startPositionFunction(worldMatrix: Matrix, positionToUpdate: Vector3, particle: Particle): void {
             var phi = Scalar.RandomRange(0, 2 * Math.PI);
             var theta = Scalar.RandomRange(0, Math.PI);
-            var randX = this.radius * Math.cos(phi) * Math.sin(theta);
-            var randY = this.radius * Math.cos(theta);
-            var randZ = this.radius * Math.sin(phi) * Math.sin(theta);
+            var randRadius = Scalar.RandomRange(0, this.radius);
+            var randX = randRadius * Math.cos(phi) * Math.sin(theta);
+            var randY = randRadius * Math.cos(theta);
+            var randZ = randRadius * Math.sin(phi) * Math.sin(theta);
             Vector3.TransformCoordinatesFromFloatsToRef(randX, randY, randZ, worldMatrix, positionToUpdate);
         }
 
@@ -100,9 +101,21 @@ module BABYLON {
          */        
         public serialize(): any {
             var serializationObject: any = {};
+            serializationObject.type = this.getClassName();
+            serializationObject.radius = this.radius;
+            serializationObject.directionRandomizer = this.directionRandomizer;
 
             return serializationObject;
-        }        
+        }    
+        
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        public parse(serializationObject: any): void {
+            this.radius = serializationObject.radius;
+            this.directionRandomizer = serializationObject.directionRandomizer;
+        }          
     }
 
     /**
@@ -113,19 +126,19 @@ module BABYLON {
 
         /**
          * Creates a new instance of @see SphereDirectedParticleEmitter
-         * @param radius the radius of the emission sphere
-         * @param direction1 the min limit of the emission direction
-         * @param direction2 the max limit of the emission direction
+         * @param radius the radius of the emission sphere (1 by default)
+         * @param direction1 the min limit of the emission direction (up vector by default)
+         * @param direction2 the max limit of the emission direction (up vector by default)
          */
-        constructor(radius: number, 
+        constructor(radius = 1, 
             /**
              * The min limit of the emission direction.
              */
-            public direction1: Vector3, 
+            public direction1 = new Vector3(0, 1, 0), 
             /**
              * The max limit of the emission direction.
              */
-            public direction2: Vector3) {
+            public direction2 = new Vector3(0, 1, 0)) {
             super(radius);
         }
 
@@ -186,9 +199,22 @@ module BABYLON {
          * @returns the JSON object
          */        
         public serialize(): any {
-            var serializationObject: any = {};
+            var serializationObject = super.serialize();;
+
+            serializationObject.direction1 = this.direction1.asArray();;
+            serializationObject.direction2 = this.direction2.asArray();;
 
             return serializationObject;
-        }        
+        }    
+        
+        /**
+         * Parse properties from a JSON object
+         * @param serializationObject defines the JSON object
+         */
+        public parse(serializationObject: any): void {
+            super.parse(serializationObject);
+            this.direction1.copyFrom(serializationObject.direction1);
+            this.direction2.copyFrom(serializationObject.direction2);
+        }           
     }
 }

+ 99 - 9
src/Particles/babylon.gpuParticleSystem.ts

@@ -1,7 +1,8 @@
 module BABYLON {
     /**
-     * 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.
+     * This represents a GPU particle system in Babylon
+     * This is the fastest particle system in Babylon as it uses the GPU to update the individual particle data
+     * @see https://www.babylonjs-playground.com/#PU4WYI
      */
     export class GPUParticleSystem implements IDisposable, IParticleSystem, IAnimatable {
         /**
@@ -27,7 +28,7 @@
         /**
          * The layer mask we are rendering the particles through.
          */
-        public layerMask: number = 0x0FFFFFFF; // TODO
+        public layerMask: number = 0x0FFFFFFF;
 
         private _capacity: number;
         private _activeCount: number;
@@ -560,9 +561,6 @@
             this.onDisposeObservable.notifyObservers(this);
             this.onDisposeObservable.clear();
         }
-
-        //TODO: Clone / Parse / serialize
-
         /**
          * Clones the particle system.
          * @param name The name of the cloned object
@@ -570,7 +568,20 @@
          * @returns the cloned particle system
          */
         public clone(name: string, newEmitter: any): Nullable<GPUParticleSystem> {
-            return null;
+            var result = new GPUParticleSystem(name, {capacity: this._capacity, randomTextureSize: this._randomTextureSize}, this._scene);
+
+            Tools.DeepCopy(this, result);
+
+            if (newEmitter === undefined) {
+                newEmitter = this.emitter;
+            }
+
+            result.emitter = newEmitter;
+            if (this.particleTexture) {
+                result.particleTexture = new Texture(this.particleTexture.url, this._scene);
+            }
+
+            return result;
         }
 
         /**
@@ -619,12 +630,91 @@
             serializationObject.targetStopDuration = this.targetStopDuration;
             serializationObject.blendMode = this.blendMode;
 
-            // Emitters
+            // Emitter
             if (this.particleEmitterType) {
-                
+                serializationObject.particleEmitterType = this.particleEmitterType.serialize();
             }
 
             return serializationObject;            
         }
+
+        /**
+         * Parses a JSON object to create a GPU particle system.
+         * @param parsedParticleSystem The JSON object to parse
+         * @param scene The scene to create the particle system in
+         * @param rootUrl The root url to use to load external dependencies like texture
+         * @returns the parsed GPU particle system
+         */
+        public static Parse(parsedParticleSystem: any, scene: Scene, rootUrl: string): GPUParticleSystem {
+            var name = parsedParticleSystem.name;
+            var particleSystem = new GPUParticleSystem(name, {capacity: parsedParticleSystem.capacity, randomTextureSize: parsedParticleSystem.randomTextureSize}, scene);
+
+            if (parsedParticleSystem.id) {
+                particleSystem.id = parsedParticleSystem.id;
+            }
+
+            // Texture
+            if (parsedParticleSystem.textureName) {
+                particleSystem.particleTexture = new Texture(rootUrl + parsedParticleSystem.textureName, scene);
+                particleSystem.particleTexture.name = parsedParticleSystem.textureName;
+            }
+
+            // Emitter
+            if (parsedParticleSystem.emitterId) {
+                particleSystem.emitter = scene.getLastMeshByID(parsedParticleSystem.emitterId);
+            } else {
+                particleSystem.emitter = Vector3.FromArray(parsedParticleSystem.emitter);
+            }
+
+            // Animations
+            if (parsedParticleSystem.animations) {
+                for (var animationIndex = 0; animationIndex < parsedParticleSystem.animations.length; animationIndex++) {
+                    var parsedAnimation = parsedParticleSystem.animations[animationIndex];
+                    particleSystem.animations.push(Animation.Parse(parsedAnimation));
+                }
+            }
+
+            // Particle system
+            particleSystem.activeParticleCount = parsedParticleSystem.activeParticleCount;
+            particleSystem.minSize = parsedParticleSystem.minSize;
+            particleSystem.maxSize = parsedParticleSystem.maxSize;
+            particleSystem.minLifeTime = parsedParticleSystem.minLifeTime;
+            particleSystem.maxLifeTime = parsedParticleSystem.maxLifeTime;
+            particleSystem.minEmitPower = parsedParticleSystem.minEmitPower;
+            particleSystem.maxEmitPower = parsedParticleSystem.maxEmitPower;
+            particleSystem.emitRate = parsedParticleSystem.emitRate;
+            particleSystem.gravity = Vector3.FromArray(parsedParticleSystem.gravity);
+            particleSystem.color1 = Color4.FromArray(parsedParticleSystem.color1);
+            particleSystem.color2 = Color4.FromArray(parsedParticleSystem.color2);
+            particleSystem.colorDead = Color4.FromArray(parsedParticleSystem.colorDead);
+            particleSystem.updateSpeed = parsedParticleSystem.updateSpeed;
+            particleSystem.targetStopDuration = parsedParticleSystem.targetStopDuration;
+            particleSystem.blendMode = parsedParticleSystem.blendMode;
+
+            // Emitter
+            if (parsedParticleSystem.particleEmitterType) {
+                let emitterType: IParticleEmitterType;
+                switch (parsedParticleSystem.particleEmitterType.type) {
+                    case "SphereEmitter":
+                        emitterType = new SphereParticleEmitter();
+                        break;
+                    case "SphereDirectedParticleEmitter":
+                        emitterType = new SphereDirectedParticleEmitter();
+                        break;
+                    case "ConeEmitter":
+                        emitterType = new ConeParticleEmitter();
+                        break;
+                    case "BoxEmitter":
+                    default:
+                        emitterType = new BoxParticleEmitter();
+                        break;                                                
+                }
+
+                emitterType.parse(parsedParticleSystem.particleEmitterType);
+                particleSystem.particleEmitterType = emitterType;
+            }
+
+            return particleSystem;
+        }        
     }
 }

+ 5 - 0
src/Particles/babylon.particleSystem.ts

@@ -1067,6 +1067,11 @@
 
             serializationObject.isAnimationSheetEnabled = this._isAnimationSheetEnabled;
 
+            // Emitter
+            if (this.particleEmitterType) {
+                serializationObject.particleEmitterType = this.particleEmitterType.serialize();
+            }            
+
             return serializationObject;
         }
 

+ 2 - 2
src/Shaders/gpuUpdateParticles.vertex.fx

@@ -105,10 +105,10 @@ void main() {
     float randY = cos(theta);
     float randZ = sin(phi) * sin(theta);
 
-    position = radius * vec3(randX, randY, randZ);
+    position = (radius * randoms2.z) * vec3(randX, randY, randZ);
 
     #ifdef DIRECTEDSPHEREEMITTER
-      direction = direction1 + (direction2 - direction1) * randoms3;
+        direction = direction1 + (direction2 - direction1) * randoms3;
     #else
         // Direction
         direction = position + directionRandomizer * randoms3;

+ 1 - 1
src/babylon.assetContainer.ts

@@ -94,7 +94,7 @@ module BABYLON {
         /**
          * ParticleSystems populated in the container.
          */
-        public particleSystems = new Array<ParticleSystem>();
+        public particleSystems = new Array<IParticleSystem>();
         /**
          * Animations populated in the container.
          */

+ 2 - 2
src/babylon.scene.ts

@@ -2389,7 +2389,7 @@
         }
 
 
-        public removeParticleSystem(toRemove: ParticleSystem): number {
+        public removeParticleSystem(toRemove: IParticleSystem): number {
             var index = this.particleSystems.indexOf(toRemove);
             if (index !== -1) {
                 this.particleSystems.splice(index, 1);
@@ -2462,7 +2462,7 @@
             this.skeletons.push(newSkeleton)
         }
 
-        public addParticleSystem(newParticleSystem: ParticleSystem) {
+        public addParticleSystem(newParticleSystem: IParticleSystem) {
             this.particleSystems.push(newParticleSystem)
         }