David Catuhe 7 年之前
父節點
當前提交
02aa4c42ce

File diff suppressed because it is too large
+ 1560 - 1494
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.js


+ 240 - 16
dist/preview release/babylon.max.js

@@ -28152,10 +28152,6 @@ var BABYLON;
             if (BABYLON.AudioEngine) {
                 this.disposeSounds();
             }
-            // VR Helper
-            if (this.VRHelper) {
-                this.VRHelper.dispose();
-            }
             // Detach cameras
             var canvas = this._engine.getRenderingCanvas();
             if (canvas) {
@@ -55685,6 +55681,8 @@ var BABYLON;
              */
             this.cellIndex = 0;
             /** @hidden */
+            this._attachedSubEmitters = null;
+            /** @hidden */
             this._currentColor1 = new BABYLON.Color4(0, 0, 0, 0);
             /** @hidden */
             this._currentColor2 = new BABYLON.Color4(0, 0, 0, 0);
@@ -55708,6 +55706,7 @@ var BABYLON;
             this._currentDrag1 = 0;
             /** @hidden */
             this._currentDrag2 = 0;
+            this.id = Particle._Count++;
             if (!this.particleSystem.isAnimationSheetEnabled) {
                 return;
             }
@@ -55772,6 +55771,8 @@ var BABYLON;
             other.angularSpeed = this.angularSpeed;
             other.particleSystem = this.particleSystem;
             other.cellIndex = this.cellIndex;
+            other.id = this.id;
+            other._attachedSubEmitters = this._attachedSubEmitters;
             if (this._currentColorGradient) {
                 other._currentColorGradient = this._currentColorGradient;
                 other._currentColor1.copyFrom(this._currentColor1);
@@ -55810,6 +55811,7 @@ var BABYLON;
                 other.remapData.copyFrom(this.remapData);
             }
         };
+        Particle._Count = 0;
         return Particle;
     }());
     BABYLON.Particle = Particle;
@@ -56457,6 +56459,10 @@ var BABYLON;
             if (epsilon === void 0) { epsilon = 0.01; }
             var _this = _super.call(this, name) || this;
             /**
+             * @hidden
+             */
+            _this._inheritedVelocityOffset = new BABYLON.Vector3();
+            /**
             * An event triggered when the system is disposed
             */
             _this.onDisposeObservable = new BABYLON.Observable();
@@ -56483,12 +56489,18 @@ var BABYLON;
             _this._currentStartSize2 = 0;
             _this._rawTextureWidth = 256;
             _this._useRampGradients = false;
+            /**
+             * @hidden
+             * If the particle systems emitter should be disposed when the particle system is disposed
+             */
+            _this._disposeEmitterOnDispose = false;
             // start of sub system methods
             /**
              * "Recycles" one of the particle by copying it back to the "stock" of particles and removing it from the active list.
              * Its lifetime will start back at 0.
              */
             _this.recycleParticle = function (particle) {
+                // move particle from activeParticle list to stock particles            
                 var lastParticle = _this._particles.pop();
                 if (lastParticle !== particle) {
                     lastParticle.copyTo(particle);
@@ -56504,17 +56516,34 @@ var BABYLON;
                 else {
                     particle = new BABYLON.Particle(_this);
                 }
+                // Attach emitters
+                if (_this._subEmitters && _this._subEmitters.length > 0) {
+                    var subEmitters = _this._subEmitters[Math.floor(Math.random() * _this._subEmitters.length)];
+                    particle._attachedSubEmitters = [];
+                    subEmitters.forEach(function (subEmitter) {
+                        if (subEmitter.type === BABYLON.SubEmitterType.ATTACHED) {
+                            var newEmitter = subEmitter.clone();
+                            particle._attachedSubEmitters.push(newEmitter);
+                            newEmitter.particleSystem.start();
+                        }
+                    });
+                }
                 return particle;
             };
             _this._emitFromParticle = function (particle) {
-                if (!_this.subEmitters || _this.subEmitters.length === 0) {
+                if (!_this._subEmitters || _this._subEmitters.length === 0) {
                     return;
                 }
-                var templateIndex = Math.floor(Math.random() * _this.subEmitters.length);
-                var subSystem = _this.subEmitters[templateIndex].clone(_this.name + "_sub", particle.position.clone());
-                subSystem._rootParticleSystem = _this;
-                _this.activeSubSystems.push(subSystem);
-                subSystem.start();
+                var templateIndex = Math.floor(Math.random() * _this._subEmitters.length);
+                _this._subEmitters[templateIndex].forEach(function (subEmitter) {
+                    if (subEmitter.type === BABYLON.SubEmitterType.END) {
+                        var subSystem = subEmitter.clone();
+                        ParticleSystem._InheritParticleInfoToSubEmitter(subSystem, particle);
+                        subSystem.particleSystem._rootParticleSystem = _this;
+                        _this.activeSubSystems.push(subSystem.particleSystem);
+                        subSystem.particleSystem.start();
+                    }
+                });
             };
             _this._capacity = capacity;
             _this._epsilon = epsilon;
@@ -56541,6 +56570,13 @@ var BABYLON;
                     particle.age += _this._scaledUpdateSpeed;
                     if (particle.age >= particle.lifeTime) { // Recycle by swapping with last particle
                         _this._emitFromParticle(particle);
+                        if (particle._attachedSubEmitters) {
+                            particle._attachedSubEmitters.forEach(function (subEmitter) {
+                                subEmitter.particleSystem.disposeOnStop = true;
+                                subEmitter.particleSystem.stop();
+                            });
+                            particle._attachedSubEmitters = null;
+                        }
                         _this.recycleParticle(particle);
                         index--;
                         return "continue";
@@ -56648,9 +56684,6 @@ var BABYLON;
                                 particle.size = BABYLON.Scalar.Lerp(particle._currentSize1, particle._currentSize2, scale);
                             });
                         }
-                        if (_this._isAnimationSheetEnabled) {
-                            particle.updateCellIndex();
-                        }
                         // Remap data
                         if (_this._useRampGradients) {
                             if (_this._colorRemapGradients && _this._colorRemapGradients.length > 0) {
@@ -56670,6 +56703,15 @@ var BABYLON;
                                 });
                             }
                         }
+                        if (_this._isAnimationSheetEnabled) {
+                            particle.updateCellIndex();
+                        }
+                        // Update the position of the attached sub-emitters to match their attached particle
+                        if (particle._attachedSubEmitters && particle._attachedSubEmitters.length > 0) {
+                            particle._attachedSubEmitters.forEach(function (subEmitter) {
+                                ParticleSystem._InheritParticleInfoToSubEmitter(subEmitter, particle);
+                            });
+                        }
                     }
                 };
                 var particle;
@@ -56727,6 +56769,27 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem._InheritParticleInfoToSubEmitter = function (subEmitter, particle) {
+            if (subEmitter.particleSystem.emitter.position) {
+                var emitterMesh = subEmitter.particleSystem.emitter;
+                emitterMesh.position.copyFrom(particle.position);
+                if (subEmitter.inheritDirection) {
+                    emitterMesh.position.subtractToRef(particle.direction, BABYLON.Tmp.Vector3[0]);
+                    // Look at using Y as forward
+                    emitterMesh.lookAt(BABYLON.Tmp.Vector3[0], 0, Math.PI / 2);
+                }
+            }
+            else {
+                var emitterPosition = subEmitter.particleSystem.emitter;
+                emitterPosition.copyFrom(particle.position);
+                if (subEmitter.inheritDirection) {
+                    BABYLON.Tools.Warn("subEmitter.inheritDirection is not supported with non-mesh emitter type");
+                }
+            }
+            // Set inheritedVelocityOffset to be used when new particles are created
+            particle.direction.scaleToRef(subEmitter.inheritedVelocityAmount / 2, BABYLON.Tmp.Vector3[0]);
+            subEmitter.particleSystem._inheritedVelocityOffset.copyFrom(BABYLON.Tmp.Vector3[0]);
+        };
         ParticleSystem.prototype._addFactorGradient = function (factorGradients, gradient, factor, factor2) {
             var newGradient = new BABYLON.FactorGradient();
             newGradient.gradient = gradient;
@@ -57241,10 +57304,25 @@ var BABYLON;
                 }, delay);
                 return;
             }
+            // Convert the subEmitters field to the constant type field _subEmitters
+            this._subEmitters = new Array();
+            if (this.subEmitters) {
+                this.subEmitters.forEach(function (subEmitter) {
+                    if (subEmitter instanceof ParticleSystem) {
+                        _this._subEmitters.push([new BABYLON.SubEmitter(subEmitter)]);
+                    }
+                    else if (subEmitter instanceof BABYLON.SubEmitter) {
+                        _this._subEmitters.push([subEmitter]);
+                    }
+                    else if (subEmitter instanceof Array) {
+                        _this._subEmitters.push(subEmitter);
+                    }
+                });
+            }
             this._started = true;
             this._stopped = false;
             this._actualFrame = 0;
-            if (this.subEmitters && this.subEmitters.length != 0) {
+            if (this._subEmitters && this._subEmitters.length != 0) {
                 this.activeSubSystems = new Array();
             }
             if (this.preWarmCycles) {
@@ -57506,6 +57584,8 @@ var BABYLON;
                     particle._initialStartSpriteCellID = this_1.startSpriteCellID;
                     particle._initialEndSpriteCellID = this_1.endSpriteCellID;
                 }
+                // Inherited Velocity
+                particle.direction.addInPlace(this_1._inheritedVelocityOffset);
                 // Remap
                 if (this_1._useRampGradients) {
                     particle.remapData = new BABYLON.Vector4(0, 1, 0, 1);
@@ -57806,6 +57886,9 @@ var BABYLON;
                 this.noiseTexture = null;
             }
             this._removeFromRoot();
+            if (this._disposeEmitterOnDispose && !this.emitter.isDisposed) {
+                this.emitter.dispose();
+            }
             // Remove from scene
             var index = this._scene.particleSystems.indexOf(this);
             if (index > -1) {
@@ -57843,6 +57926,52 @@ var BABYLON;
             if (this.particleTexture) {
                 result.particleTexture = new BABYLON.Texture(this.particleTexture.url, this._scene);
             }
+            // Clone gradients
+            if (this._colorGradients) {
+                this._colorGradients.forEach(function (v) {
+                    result.addColorGradient(v.gradient, v.color1, v.color2);
+                });
+            }
+            if (this._dragGradients) {
+                this._dragGradients.forEach(function (v) {
+                    result.addDragGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._angularSpeedGradients) {
+                this._angularSpeedGradients.forEach(function (v) {
+                    result.addAngularSpeedGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._emitRateGradients) {
+                this._emitRateGradients.forEach(function (v) {
+                    result.addEmitRateGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._lifeTimeGradients) {
+                this._lifeTimeGradients.forEach(function (v) {
+                    result.addLifeTimeGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._limitVelocityGradients) {
+                this._limitVelocityGradients.forEach(function (v) {
+                    result.addLimitVelocityGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._sizeGradients) {
+                this._sizeGradients.forEach(function (v) {
+                    result.addSizeGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._startSizeGradients) {
+                this._startSizeGradients.forEach(function (v) {
+                    result.addStartSizeGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._velocityGradients) {
+                this._velocityGradients.forEach(function (v) {
+                    result.addVelocityGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
             if (!this.preventAutoStart) {
                 result.start();
             }
@@ -59333,6 +59462,81 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.particleSystemComponent.js.map
 
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Type of sub emitter
+     */
+    var SubEmitterType;
+    (function (SubEmitterType) {
+        /**
+         * Attached to the particle over it's lifetime
+         */
+        SubEmitterType[SubEmitterType["ATTACHED"] = 0] = "ATTACHED";
+        /**
+         * Created when the particle dies
+         */
+        SubEmitterType[SubEmitterType["END"] = 1] = "END";
+    })(SubEmitterType = BABYLON.SubEmitterType || (BABYLON.SubEmitterType = {}));
+    /**
+     * Sub emitter class used to emit particles from an existing particle
+     */
+    var SubEmitter = /** @class */ (function () {
+        /**
+         * Creates a sub emitter
+         * @param particleSystem the particle system to be used by the sub emitter
+         */
+        function SubEmitter(
+        /**
+         * the particle system to be used by the sub emitter
+         */
+        particleSystem) {
+            this.particleSystem = particleSystem;
+            /**
+             * Type of the submitter (Default: END)
+             */
+            this.type = SubEmitterType.END;
+            /**
+             * If the particle should inherit the direction from the particle it's attached to. (+Y will face the direction the particle is moving) (Default: false)
+             * Note: This only is supported when using an emitter of type Mesh
+             */
+            this.inheritDirection = false;
+            /**
+             * How much of the attached particles speed should be added to the sub emitted particle (default: 0)
+             */
+            this.inheritedVelocityAmount = 0;
+        }
+        /**
+         * Clones the sub emitter
+         * @returns the cloned sub emitter
+         */
+        SubEmitter.prototype.clone = function () {
+            // Clone particle system
+            var emitter = this.particleSystem.emitter;
+            if (!emitter) {
+                emitter = new BABYLON.Vector3();
+            }
+            else if (emitter instanceof BABYLON.Vector3) {
+                emitter = emitter.clone();
+            }
+            else if (emitter instanceof BABYLON.AbstractMesh) {
+                emitter = new BABYLON.Mesh("", emitter._scene);
+            }
+            var clone = new SubEmitter(this.particleSystem.clone("", emitter));
+            // Clone properties
+            clone.type = this.type;
+            clone.inheritDirection = this.inheritDirection;
+            clone.inheritedVelocityAmount = this.inheritedVelocityAmount;
+            clone.particleSystem._disposeEmitterOnDispose = true;
+            return clone;
+        };
+        return SubEmitter;
+    }());
+    BABYLON.SubEmitter = SubEmitter;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.subEmitter.js.map
+
 
 var BABYLON;
 (function (BABYLON) {
@@ -81391,6 +81595,7 @@ var BABYLON;
             _this._hasCleared = false;
             _this._prevPostProcess = null;
             _this._prevPrevPostProcess = null;
+            _this._depthOfFieldSceneObserver = null;
             _this._cameras = cameras || scene.cameras;
             _this._cameras = _this._cameras.slice();
             _this._camerasToBeAttached = _this._cameras.slice();
@@ -81742,14 +81947,32 @@ var BABYLON;
             this._prevPrevPostProcess = null;
             this._hasCleared = false;
             if (this.depthOfFieldEnabled) {
-                var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
-                this.depthOfField.depthTexture = depthTexture;
+                // Multi camera suport
+                if (this._cameras.length > 1) {
+                    for (var _i = 0, _a = this._cameras; _i < _a.length; _i++) {
+                        var camera = _a[_i];
+                        this._scene.enableDepthRenderer(camera).getDepthMap();
+                    }
+                    this._depthOfFieldSceneObserver = this._scene.onAfterRenderTargetsRenderObservable.add(function (scene) {
+                        if (_this._cameras.indexOf(scene.activeCamera) > -1) {
+                            _this.depthOfField.depthTexture = scene.enableDepthRenderer(scene.activeCamera).getDepthMap();
+                        }
+                    });
+                }
+                else {
+                    this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
+                    var depthRenderer = this._scene.enableDepthRenderer(this._cameras[0]);
+                    this.depthOfField.depthTexture = depthRenderer.getDepthMap();
+                }
                 if (!this.depthOfField._isReady()) {
                     this.depthOfField._updateEffects();
                 }
                 this.addEffect(this.depthOfField);
                 this._setAutoClearAndTextureSharing(this.depthOfField._effects[0], true);
             }
+            else {
+                this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
+            }
             if (this.bloomEnabled) {
                 if (!this.bloom._isReady()) {
                     this.bloom._updateEffects();
@@ -81816,6 +82039,7 @@ var BABYLON;
                         this.sharpen.dispose(camera);
                     }
                     if (this.depthOfField) {
+                        this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
                         this.depthOfField.disposeEffects(camera);
                     }
                     if (this.bloom) {

+ 240 - 16
dist/preview release/babylon.no-module.max.js

@@ -28119,10 +28119,6 @@ var BABYLON;
             if (BABYLON.AudioEngine) {
                 this.disposeSounds();
             }
-            // VR Helper
-            if (this.VRHelper) {
-                this.VRHelper.dispose();
-            }
             // Detach cameras
             var canvas = this._engine.getRenderingCanvas();
             if (canvas) {
@@ -55652,6 +55648,8 @@ var BABYLON;
              */
             this.cellIndex = 0;
             /** @hidden */
+            this._attachedSubEmitters = null;
+            /** @hidden */
             this._currentColor1 = new BABYLON.Color4(0, 0, 0, 0);
             /** @hidden */
             this._currentColor2 = new BABYLON.Color4(0, 0, 0, 0);
@@ -55675,6 +55673,7 @@ var BABYLON;
             this._currentDrag1 = 0;
             /** @hidden */
             this._currentDrag2 = 0;
+            this.id = Particle._Count++;
             if (!this.particleSystem.isAnimationSheetEnabled) {
                 return;
             }
@@ -55739,6 +55738,8 @@ var BABYLON;
             other.angularSpeed = this.angularSpeed;
             other.particleSystem = this.particleSystem;
             other.cellIndex = this.cellIndex;
+            other.id = this.id;
+            other._attachedSubEmitters = this._attachedSubEmitters;
             if (this._currentColorGradient) {
                 other._currentColorGradient = this._currentColorGradient;
                 other._currentColor1.copyFrom(this._currentColor1);
@@ -55777,6 +55778,7 @@ var BABYLON;
                 other.remapData.copyFrom(this.remapData);
             }
         };
+        Particle._Count = 0;
         return Particle;
     }());
     BABYLON.Particle = Particle;
@@ -56424,6 +56426,10 @@ var BABYLON;
             if (epsilon === void 0) { epsilon = 0.01; }
             var _this = _super.call(this, name) || this;
             /**
+             * @hidden
+             */
+            _this._inheritedVelocityOffset = new BABYLON.Vector3();
+            /**
             * An event triggered when the system is disposed
             */
             _this.onDisposeObservable = new BABYLON.Observable();
@@ -56450,12 +56456,18 @@ var BABYLON;
             _this._currentStartSize2 = 0;
             _this._rawTextureWidth = 256;
             _this._useRampGradients = false;
+            /**
+             * @hidden
+             * If the particle systems emitter should be disposed when the particle system is disposed
+             */
+            _this._disposeEmitterOnDispose = false;
             // start of sub system methods
             /**
              * "Recycles" one of the particle by copying it back to the "stock" of particles and removing it from the active list.
              * Its lifetime will start back at 0.
              */
             _this.recycleParticle = function (particle) {
+                // move particle from activeParticle list to stock particles            
                 var lastParticle = _this._particles.pop();
                 if (lastParticle !== particle) {
                     lastParticle.copyTo(particle);
@@ -56471,17 +56483,34 @@ var BABYLON;
                 else {
                     particle = new BABYLON.Particle(_this);
                 }
+                // Attach emitters
+                if (_this._subEmitters && _this._subEmitters.length > 0) {
+                    var subEmitters = _this._subEmitters[Math.floor(Math.random() * _this._subEmitters.length)];
+                    particle._attachedSubEmitters = [];
+                    subEmitters.forEach(function (subEmitter) {
+                        if (subEmitter.type === BABYLON.SubEmitterType.ATTACHED) {
+                            var newEmitter = subEmitter.clone();
+                            particle._attachedSubEmitters.push(newEmitter);
+                            newEmitter.particleSystem.start();
+                        }
+                    });
+                }
                 return particle;
             };
             _this._emitFromParticle = function (particle) {
-                if (!_this.subEmitters || _this.subEmitters.length === 0) {
+                if (!_this._subEmitters || _this._subEmitters.length === 0) {
                     return;
                 }
-                var templateIndex = Math.floor(Math.random() * _this.subEmitters.length);
-                var subSystem = _this.subEmitters[templateIndex].clone(_this.name + "_sub", particle.position.clone());
-                subSystem._rootParticleSystem = _this;
-                _this.activeSubSystems.push(subSystem);
-                subSystem.start();
+                var templateIndex = Math.floor(Math.random() * _this._subEmitters.length);
+                _this._subEmitters[templateIndex].forEach(function (subEmitter) {
+                    if (subEmitter.type === BABYLON.SubEmitterType.END) {
+                        var subSystem = subEmitter.clone();
+                        ParticleSystem._InheritParticleInfoToSubEmitter(subSystem, particle);
+                        subSystem.particleSystem._rootParticleSystem = _this;
+                        _this.activeSubSystems.push(subSystem.particleSystem);
+                        subSystem.particleSystem.start();
+                    }
+                });
             };
             _this._capacity = capacity;
             _this._epsilon = epsilon;
@@ -56508,6 +56537,13 @@ var BABYLON;
                     particle.age += _this._scaledUpdateSpeed;
                     if (particle.age >= particle.lifeTime) { // Recycle by swapping with last particle
                         _this._emitFromParticle(particle);
+                        if (particle._attachedSubEmitters) {
+                            particle._attachedSubEmitters.forEach(function (subEmitter) {
+                                subEmitter.particleSystem.disposeOnStop = true;
+                                subEmitter.particleSystem.stop();
+                            });
+                            particle._attachedSubEmitters = null;
+                        }
                         _this.recycleParticle(particle);
                         index--;
                         return "continue";
@@ -56615,9 +56651,6 @@ var BABYLON;
                                 particle.size = BABYLON.Scalar.Lerp(particle._currentSize1, particle._currentSize2, scale);
                             });
                         }
-                        if (_this._isAnimationSheetEnabled) {
-                            particle.updateCellIndex();
-                        }
                         // Remap data
                         if (_this._useRampGradients) {
                             if (_this._colorRemapGradients && _this._colorRemapGradients.length > 0) {
@@ -56637,6 +56670,15 @@ var BABYLON;
                                 });
                             }
                         }
+                        if (_this._isAnimationSheetEnabled) {
+                            particle.updateCellIndex();
+                        }
+                        // Update the position of the attached sub-emitters to match their attached particle
+                        if (particle._attachedSubEmitters && particle._attachedSubEmitters.length > 0) {
+                            particle._attachedSubEmitters.forEach(function (subEmitter) {
+                                ParticleSystem._InheritParticleInfoToSubEmitter(subEmitter, particle);
+                            });
+                        }
                     }
                 };
                 var particle;
@@ -56694,6 +56736,27 @@ var BABYLON;
         ParticleSystem.prototype.getClassName = function () {
             return "ParticleSystem";
         };
+        ParticleSystem._InheritParticleInfoToSubEmitter = function (subEmitter, particle) {
+            if (subEmitter.particleSystem.emitter.position) {
+                var emitterMesh = subEmitter.particleSystem.emitter;
+                emitterMesh.position.copyFrom(particle.position);
+                if (subEmitter.inheritDirection) {
+                    emitterMesh.position.subtractToRef(particle.direction, BABYLON.Tmp.Vector3[0]);
+                    // Look at using Y as forward
+                    emitterMesh.lookAt(BABYLON.Tmp.Vector3[0], 0, Math.PI / 2);
+                }
+            }
+            else {
+                var emitterPosition = subEmitter.particleSystem.emitter;
+                emitterPosition.copyFrom(particle.position);
+                if (subEmitter.inheritDirection) {
+                    BABYLON.Tools.Warn("subEmitter.inheritDirection is not supported with non-mesh emitter type");
+                }
+            }
+            // Set inheritedVelocityOffset to be used when new particles are created
+            particle.direction.scaleToRef(subEmitter.inheritedVelocityAmount / 2, BABYLON.Tmp.Vector3[0]);
+            subEmitter.particleSystem._inheritedVelocityOffset.copyFrom(BABYLON.Tmp.Vector3[0]);
+        };
         ParticleSystem.prototype._addFactorGradient = function (factorGradients, gradient, factor, factor2) {
             var newGradient = new BABYLON.FactorGradient();
             newGradient.gradient = gradient;
@@ -57208,10 +57271,25 @@ var BABYLON;
                 }, delay);
                 return;
             }
+            // Convert the subEmitters field to the constant type field _subEmitters
+            this._subEmitters = new Array();
+            if (this.subEmitters) {
+                this.subEmitters.forEach(function (subEmitter) {
+                    if (subEmitter instanceof ParticleSystem) {
+                        _this._subEmitters.push([new BABYLON.SubEmitter(subEmitter)]);
+                    }
+                    else if (subEmitter instanceof BABYLON.SubEmitter) {
+                        _this._subEmitters.push([subEmitter]);
+                    }
+                    else if (subEmitter instanceof Array) {
+                        _this._subEmitters.push(subEmitter);
+                    }
+                });
+            }
             this._started = true;
             this._stopped = false;
             this._actualFrame = 0;
-            if (this.subEmitters && this.subEmitters.length != 0) {
+            if (this._subEmitters && this._subEmitters.length != 0) {
                 this.activeSubSystems = new Array();
             }
             if (this.preWarmCycles) {
@@ -57473,6 +57551,8 @@ var BABYLON;
                     particle._initialStartSpriteCellID = this_1.startSpriteCellID;
                     particle._initialEndSpriteCellID = this_1.endSpriteCellID;
                 }
+                // Inherited Velocity
+                particle.direction.addInPlace(this_1._inheritedVelocityOffset);
                 // Remap
                 if (this_1._useRampGradients) {
                     particle.remapData = new BABYLON.Vector4(0, 1, 0, 1);
@@ -57773,6 +57853,9 @@ var BABYLON;
                 this.noiseTexture = null;
             }
             this._removeFromRoot();
+            if (this._disposeEmitterOnDispose && !this.emitter.isDisposed) {
+                this.emitter.dispose();
+            }
             // Remove from scene
             var index = this._scene.particleSystems.indexOf(this);
             if (index > -1) {
@@ -57810,6 +57893,52 @@ var BABYLON;
             if (this.particleTexture) {
                 result.particleTexture = new BABYLON.Texture(this.particleTexture.url, this._scene);
             }
+            // Clone gradients
+            if (this._colorGradients) {
+                this._colorGradients.forEach(function (v) {
+                    result.addColorGradient(v.gradient, v.color1, v.color2);
+                });
+            }
+            if (this._dragGradients) {
+                this._dragGradients.forEach(function (v) {
+                    result.addDragGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._angularSpeedGradients) {
+                this._angularSpeedGradients.forEach(function (v) {
+                    result.addAngularSpeedGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._emitRateGradients) {
+                this._emitRateGradients.forEach(function (v) {
+                    result.addEmitRateGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._lifeTimeGradients) {
+                this._lifeTimeGradients.forEach(function (v) {
+                    result.addLifeTimeGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._limitVelocityGradients) {
+                this._limitVelocityGradients.forEach(function (v) {
+                    result.addLimitVelocityGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._sizeGradients) {
+                this._sizeGradients.forEach(function (v) {
+                    result.addSizeGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._startSizeGradients) {
+                this._startSizeGradients.forEach(function (v) {
+                    result.addStartSizeGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
+            if (this._velocityGradients) {
+                this._velocityGradients.forEach(function (v) {
+                    result.addVelocityGradient(v.gradient, v.factor1, v.factor2);
+                });
+            }
             if (!this.preventAutoStart) {
                 result.start();
             }
@@ -59300,6 +59429,81 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.particleSystemComponent.js.map
 
+var BABYLON;
+(function (BABYLON) {
+    /**
+     * Type of sub emitter
+     */
+    var SubEmitterType;
+    (function (SubEmitterType) {
+        /**
+         * Attached to the particle over it's lifetime
+         */
+        SubEmitterType[SubEmitterType["ATTACHED"] = 0] = "ATTACHED";
+        /**
+         * Created when the particle dies
+         */
+        SubEmitterType[SubEmitterType["END"] = 1] = "END";
+    })(SubEmitterType = BABYLON.SubEmitterType || (BABYLON.SubEmitterType = {}));
+    /**
+     * Sub emitter class used to emit particles from an existing particle
+     */
+    var SubEmitter = /** @class */ (function () {
+        /**
+         * Creates a sub emitter
+         * @param particleSystem the particle system to be used by the sub emitter
+         */
+        function SubEmitter(
+        /**
+         * the particle system to be used by the sub emitter
+         */
+        particleSystem) {
+            this.particleSystem = particleSystem;
+            /**
+             * Type of the submitter (Default: END)
+             */
+            this.type = SubEmitterType.END;
+            /**
+             * If the particle should inherit the direction from the particle it's attached to. (+Y will face the direction the particle is moving) (Default: false)
+             * Note: This only is supported when using an emitter of type Mesh
+             */
+            this.inheritDirection = false;
+            /**
+             * How much of the attached particles speed should be added to the sub emitted particle (default: 0)
+             */
+            this.inheritedVelocityAmount = 0;
+        }
+        /**
+         * Clones the sub emitter
+         * @returns the cloned sub emitter
+         */
+        SubEmitter.prototype.clone = function () {
+            // Clone particle system
+            var emitter = this.particleSystem.emitter;
+            if (!emitter) {
+                emitter = new BABYLON.Vector3();
+            }
+            else if (emitter instanceof BABYLON.Vector3) {
+                emitter = emitter.clone();
+            }
+            else if (emitter instanceof BABYLON.AbstractMesh) {
+                emitter = new BABYLON.Mesh("", emitter._scene);
+            }
+            var clone = new SubEmitter(this.particleSystem.clone("", emitter));
+            // Clone properties
+            clone.type = this.type;
+            clone.inheritDirection = this.inheritDirection;
+            clone.inheritedVelocityAmount = this.inheritedVelocityAmount;
+            clone.particleSystem._disposeEmitterOnDispose = true;
+            return clone;
+        };
+        return SubEmitter;
+    }());
+    BABYLON.SubEmitter = SubEmitter;
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=babylon.subEmitter.js.map
+
 
 var BABYLON;
 (function (BABYLON) {
@@ -81358,6 +81562,7 @@ var BABYLON;
             _this._hasCleared = false;
             _this._prevPostProcess = null;
             _this._prevPrevPostProcess = null;
+            _this._depthOfFieldSceneObserver = null;
             _this._cameras = cameras || scene.cameras;
             _this._cameras = _this._cameras.slice();
             _this._camerasToBeAttached = _this._cameras.slice();
@@ -81709,14 +81914,32 @@ var BABYLON;
             this._prevPrevPostProcess = null;
             this._hasCleared = false;
             if (this.depthOfFieldEnabled) {
-                var depthTexture = this._scene.enableDepthRenderer(this._cameras[0]).getDepthMap();
-                this.depthOfField.depthTexture = depthTexture;
+                // Multi camera suport
+                if (this._cameras.length > 1) {
+                    for (var _i = 0, _a = this._cameras; _i < _a.length; _i++) {
+                        var camera = _a[_i];
+                        this._scene.enableDepthRenderer(camera).getDepthMap();
+                    }
+                    this._depthOfFieldSceneObserver = this._scene.onAfterRenderTargetsRenderObservable.add(function (scene) {
+                        if (_this._cameras.indexOf(scene.activeCamera) > -1) {
+                            _this.depthOfField.depthTexture = scene.enableDepthRenderer(scene.activeCamera).getDepthMap();
+                        }
+                    });
+                }
+                else {
+                    this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
+                    var depthRenderer = this._scene.enableDepthRenderer(this._cameras[0]);
+                    this.depthOfField.depthTexture = depthRenderer.getDepthMap();
+                }
                 if (!this.depthOfField._isReady()) {
                     this.depthOfField._updateEffects();
                 }
                 this.addEffect(this.depthOfField);
                 this._setAutoClearAndTextureSharing(this.depthOfField._effects[0], true);
             }
+            else {
+                this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
+            }
             if (this.bloomEnabled) {
                 if (!this.bloom._isReady()) {
                     this.bloom._updateEffects();
@@ -81783,6 +82006,7 @@ var BABYLON;
                         this.sharpen.dispose(camera);
                     }
                     if (this.depthOfField) {
+                        this._scene.onAfterRenderTargetsRenderObservable.remove(this._depthOfFieldSceneObserver);
                         this.depthOfField.disposeEffects(camera);
                     }
                     if (this.bloom) {

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.worker.js


File diff suppressed because it is too large
+ 242 - 18
dist/preview release/es6.js


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

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

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


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

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

File diff suppressed because it is too large
+ 198 - 183
src/Particles/babylon.particleSystem.ts