David Catuhe 7 år sedan
förälder
incheckning
be6e0e4099

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1184 - 1184
Playground/babylon.d.txt


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 11613 - 11477
dist/preview release/babylon.d.ts


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 1
dist/preview release/babylon.js


+ 242 - 47
dist/preview release/babylon.max.js

@@ -19647,20 +19647,10 @@ var BABYLON;
              */
             _this.renderingGroupId = 0;
             _this._receiveShadows = false;
-            /**
-             * Gets or sets a boolean indicating if the outline must be rendered as well
-             * @see https://www.babylonjs-playground.com/#10WJ5S#3
-             */
-            _this.renderOutline = false;
             /** Defines color to use when rendering outline */
             _this.outlineColor = BABYLON.Color3.Red();
             /** Define width to use when rendering outline */
             _this.outlineWidth = 0.02;
-            /**
-             * Gets or sets a boolean indicating if the overlay must be rendered as well
-             * @see https://www.babylonjs-playground.com/#10WJ5S#2
-             */
-            _this.renderOverlay = false;
             /** Defines color to use when rendering overlay */
             _this.overlayColor = BABYLON.Color3.Red();
             /** Defines alpha to use when rendering overlay */
@@ -23736,6 +23726,7 @@ var BABYLON;
         SceneComponentConstants.NAME_DEPTHRENDERER = "DepthRenderer";
         SceneComponentConstants.NAME_POSTPROCESSRENDERPIPELINEMANAGER = "PostProcessRenderPipelineManager";
         SceneComponentConstants.NAME_SPRITE = "Sprite";
+        SceneComponentConstants.NAME_OUTLINERENDERER = "Outline";
         SceneComponentConstants.STEP_ISREADYFORMESH_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER = 0;
         SceneComponentConstants.STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER = 0;
@@ -23743,6 +23734,8 @@ var BABYLON;
         SceneComponentConstants.STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER = 1;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER = 1;
+        SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE = 0;
+        SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE = 0;
         SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE = 0;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_GAMEPAD = 1;
@@ -24486,11 +24479,22 @@ var BABYLON;
              */
             _this._beforeCameraDrawStage = BABYLON.Stage.Create();
             /**
+             * @hidden
              * Defines the actions happening just before a rendering group is drawing.
              */
             _this._beforeRenderingGroupDrawStage = BABYLON.Stage.Create();
             /**
              * @hidden
+             * Defines the actions happening just before a mesh is drawing.
+             */
+            _this._beforeRenderingMeshStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
+             * Defines the actions happening just after a mesh has been drawn.
+             */
+            _this._afterRenderingMeshStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
              * Defines the actions happening just after a rendering group has been drawn.
              */
             _this._afterRenderingGroupDrawStage = BABYLON.Stage.Create();
@@ -24532,9 +24536,6 @@ var BABYLON;
             if (BABYLON.PostProcessManager) {
                 _this.postProcessManager = new BABYLON.PostProcessManager(_this);
             }
-            if (BABYLON.OutlineRenderer) {
-                _this._outlineRenderer = new BABYLON.OutlineRenderer(_this);
-            }
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 _this.attachControl();
             }
@@ -25051,13 +25052,6 @@ var BABYLON;
             return this._cachedEffect !== effect || this._cachedMaterial !== material || this._cachedVisibility !== visibility;
         };
         /**
-         * Gets the outline renderer associated with the scene
-         * @returns a OutlineRenderer
-         */
-        Scene.prototype.getOutlineRenderer = function () {
-            return this._outlineRenderer;
-        };
-        /**
          * Gets the engine associated with the scene
          * @returns an Engine
          */
@@ -28125,6 +28119,8 @@ var BABYLON;
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
+            this._beforeRenderingMeshStage.clear();
+            this._afterRenderingMeshStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
             this._beforeCameraUpdateStage.clear();
@@ -32391,12 +32387,9 @@ var BABYLON;
             if (enableAlphaMode) {
                 engine.setAlphaMode(this._effectiveMaterial.alphaMode);
             }
-            // Outline - step 1
-            var savedDepthWrite = engine.getDepthWrite();
-            if (this.renderOutline) {
-                engine.setDepthWrite(false);
-                scene.getOutlineRenderer().render(subMesh, batch);
-                engine.setDepthWrite(savedDepthWrite);
+            for (var _i = 0, _a = scene._beforeRenderingMeshStage; _i < _a.length; _i++) {
+                var step = _a[_i];
+                step.action(this, subMesh, batch);
             }
             var effect;
             if (this._effectiveMaterial.storeEffectOnSubMeshes) {
@@ -32440,19 +32433,9 @@ var BABYLON;
             this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, this._effectiveMaterial);
             // Unbind
             this._effectiveMaterial.unbind();
-            // Outline - step 2
-            if (this.renderOutline && savedDepthWrite) {
-                engine.setDepthWrite(true);
-                engine.setColorWrite(false);
-                scene.getOutlineRenderer().render(subMesh, batch);
-                engine.setColorWrite(true);
-            }
-            // Overlay
-            if (this.renderOverlay) {
-                var currentMode = engine.getAlphaMode();
-                engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
-                scene.getOutlineRenderer().render(subMesh, batch, true);
-                engine.setAlphaMode(currentMode);
+            for (var _b = 0, _c = scene._afterRenderingMeshStage; _b < _c.length; _b++) {
+                var step = _c[_b];
+                step.action(this, subMesh, batch);
             }
             if (this._onAfterRenderObservable) {
                 this._onAfterRenderObservable.notifyObservers(this);
@@ -56167,6 +56150,7 @@ var BABYLON;
             this._limitVelocityGradients = null;
             this._dragGradients = null;
             this._emitRateGradients = null;
+            this._startSizeGradients = null;
             /** Gets or sets a value indicating the damping to apply if the limit velocity factor is reached */
             this.limitVelocityDamping = 0.4;
             /**
@@ -56279,6 +56263,14 @@ var BABYLON;
             return this._velocityGradients;
         };
         /**
+         * Gets the current list of start size gradients.
+         * You must use addStartSizeGradient and removeStartSizeGradient to udpate this list
+         * @returns the list of start size gradients
+         */
+        BaseParticleSystem.prototype.getStartSizeGradients = function () {
+            return this._startSizeGradients;
+        };
+        /**
          * Gets the current list of emit rate gradients.
          * You must use addEmitRateGradient and removeEmitRateGradient to udpate this list
          * @returns the list of emit rate gradients
@@ -56587,6 +56579,10 @@ var BABYLON;
             _this._currentEmitRate1 = 0;
             /** @hidden */
             _this._currentEmitRate2 = 0;
+            /** @hidden */
+            _this._currentStartSize1 = 0;
+            /** @hidden */
+            _this._currentStartSize2 = 0;
             // 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.
@@ -56997,6 +56993,37 @@ var BABYLON;
             return this;
         };
         /**
+         * Adds a new start size gradient (please note that this will only work if you set the targetStopDuration property)
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the start size value to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.addStartSizeGradient = function (gradient, factor, factor2) {
+            if (!this._startSizeGradients) {
+                this._startSizeGradients = [];
+            }
+            this._addFactorGradient(this._startSizeGradients, gradient, factor, factor2);
+            if (!this._currentStartSizeGradient) {
+                this._currentStartSizeGradient = this._startSizeGradients[0];
+                this._currentStartSize1 = this._currentStartSizeGradient.getFactor();
+                this._currentStartSize2 = this._currentStartSize1;
+            }
+            if (this._startSizeGradients.length === 2) {
+                this._currentStartSize2 = this._startSizeGradients[1].getFactor();
+            }
+            return this;
+        };
+        /**
+         * Remove a specific start size gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.removeStartSizeGradient = function (gradient) {
+            this._removeFactorGradient(this._emitRateGradients, gradient);
+            return this;
+        };
+        /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
          * @param color defines the color to affect to the specified gradient
@@ -57256,6 +57283,7 @@ var BABYLON;
         };
         // End of sub system methods
         ParticleSystem.prototype._update = function (newParticles) {
+            var _this = this;
             // Update current
             this._alive = this._particles.length > 0;
             if (this.emitter.position) {
@@ -57333,6 +57361,19 @@ var BABYLON;
                 }
                 // Size and scale
                 particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this_1.minScaleX, this_1.maxScaleX), BABYLON.Scalar.RandomRange(this_1.minScaleY, this_1.maxScaleY));
+                // Adjust scale by start size
+                if (this_1._startSizeGradients && this_1._startSizeGradients[0]) {
+                    var ratio = this_1._actualFrame / this_1.targetStopDuration;
+                    BABYLON.Tools.GetCurrentGradient(ratio, this_1._startSizeGradients, function (currentGradient, nextGradient, scale) {
+                        if (currentGradient !== _this._currentStartSizeGradient) {
+                            _this._currentStartSize1 = _this._currentStartSize2;
+                            _this._currentStartSize2 = nextGradient.getFactor();
+                            _this._currentStartSizeGradient = currentGradient;
+                        }
+                        var value = BABYLON.Scalar.Lerp(_this._currentStartSize1, _this._currentStartSize2, scale);
+                        particle.scale.scaleInPlace(value);
+                    });
+                }
                 // Angle
                 if (!this_1._angularSpeedGradients || this_1._angularSpeedGradients.length === 0) {
                     particle.angularSpeed = BABYLON.Scalar.RandomRange(this_1.minAngularSpeed, this_1.maxAngularSpeed);
@@ -57896,11 +57937,26 @@ var BABYLON;
                     serializationObject.emitRateGradients.push(serializedGradient);
                 }
             }
+            var startSizeGradients = particleSystem.getStartSizeGradients();
+            if (startSizeGradients) {
+                serializationObject.startSizeGradients = [];
+                for (var _f = 0, startSizeGradients_1 = startSizeGradients; _f < startSizeGradients_1.length; _f++) {
+                    var startSizeGradient = startSizeGradients_1[_f];
+                    var serializedGradient = {
+                        gradient: startSizeGradient.gradient,
+                        factor1: startSizeGradient.factor1
+                    };
+                    if (startSizeGradient.factor2 !== undefined) {
+                        serializedGradient.factor2 = startSizeGradient.factor2;
+                    }
+                    serializationObject.startSizeGradients.push(serializedGradient);
+                }
+            }
             var limitVelocityGradients = particleSystem.getLimitVelocityGradients();
             if (limitVelocityGradients) {
                 serializationObject.limitVelocityGradients = [];
-                for (var _f = 0, limitVelocityGradients_1 = limitVelocityGradients; _f < limitVelocityGradients_1.length; _f++) {
-                    var limitVelocityGradient = limitVelocityGradients_1[_f];
+                for (var _g = 0, limitVelocityGradients_1 = limitVelocityGradients; _g < limitVelocityGradients_1.length; _g++) {
+                    var limitVelocityGradient = limitVelocityGradients_1[_g];
                     var serializedGradient = {
                         gradient: limitVelocityGradient.gradient,
                         factor1: limitVelocityGradient.factor1
@@ -58021,9 +58077,15 @@ var BABYLON;
                     particleSystem.addEmitRateGradient(emitRateGradient.gradient, emitRateGradient.factor1 !== undefined ? emitRateGradient.factor1 : emitRateGradient.factor, emitRateGradient.factor2);
                 }
             }
+            if (parsedParticleSystem.startSizeGradients) {
+                for (var _m = 0, _o = parsedParticleSystem.startSizeGradients; _m < _o.length; _m++) {
+                    var startSizeGradient = _o[_m];
+                    particleSystem.addStartSizeGradient(startSizeGradient.gradient, startSizeGradient.factor1 !== undefined ? startSizeGradient.factor1 : startSizeGradient.factor, startSizeGradient.factor2);
+                }
+            }
             if (parsedParticleSystem.limitVelocityGradients) {
-                for (var _m = 0, _o = parsedParticleSystem.limitVelocityGradients; _m < _o.length; _m++) {
-                    var limitVelocityGradient = _o[_m];
+                for (var _p = 0, _q = parsedParticleSystem.limitVelocityGradients; _p < _q.length; _p++) {
+                    var limitVelocityGradient = _q[_p];
                     particleSystem.addLimitVelocityGradient(limitVelocityGradient.gradient, limitVelocityGradient.factor1 !== undefined ? limitVelocityGradient.factor1 : limitVelocityGradient.factor, limitVelocityGradient.factor2);
                 }
                 particleSystem.limitVelocityDamping = parsedParticleSystem.limitVelocityDamping;
@@ -61803,6 +61865,26 @@ var BABYLON;
             // Do nothing as emit rate is not supported by GPUParticleSystem
             return this;
         };
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the start size value to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.addStartSizeGradient = function (gradient, factor, factor2) {
+            // Do nothing as start size is not supported by GPUParticleSystem
+            return this;
+        };
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.removeStartSizeGradient = function (gradient) {
+            // Do nothing as start size is not supported by GPUParticleSystem
+            return this;
+        };
         GPUParticleSystem.prototype._reset = function () {
             this._releaseBuffers();
         };
@@ -100324,16 +100406,97 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * Gets the outline renderer associated with the scene
+     * @returns a OutlineRenderer
+     */
+    BABYLON.Scene.prototype.getOutlineRenderer = function () {
+        if (!this._outlineRenderer) {
+            this._outlineRenderer = new OutlineRenderer(this);
+        }
+        return this._outlineRenderer;
+    };
+    Object.defineProperty(BABYLON.AbstractMesh.prototype, "renderOutline", {
+        get: function () {
+            return this._renderOutline;
+        },
+        set: function (value) {
+            if (value) {
+                // Lazy Load the component.
+                this.getScene().getOutlineRenderer();
+            }
+            this._renderOutline = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BABYLON.AbstractMesh.prototype, "renderOverlay", {
+        get: function () {
+            return this._renderOverlay;
+        },
+        set: function (value) {
+            if (value) {
+                // Lazy Load the component.
+                this.getScene().getOutlineRenderer();
+            }
+            this._renderOverlay = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /**
+     * This class is responsible to draw bothe outline/overlay of meshes.
+     * It should not be used directly but through the available method on mesh.
+     */
     var OutlineRenderer = /** @class */ (function () {
+        /**
+         * Instantiates a new outline renderer. (There could be only one per scene).
+         * @param scene Defines the scene it belongs to
+         */
         function OutlineRenderer(scene) {
+            /**
+             * The name of the component. Each component must have a unique name.
+             */
+            this.name = BABYLON.SceneComponentConstants.NAME_OUTLINERENDERER;
+            /**
+             * Defines a zOffset to prevent zFighting between the overlay and the mesh.
+             */
             this.zOffset = 1;
-            this._scene = scene;
+            this.scene = scene;
+            this._engine = scene.getEngine();
+            this.scene._addComponent(this);
         }
+        /**
+         * Register the component to one instance of a scene.
+         */
+        OutlineRenderer.prototype.register = function () {
+            this.scene._beforeRenderingMeshStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE, this, this._beforeRenderingMesh);
+            this.scene._afterRenderingMeshStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE, this, this._afterRenderingMesh);
+        };
+        /**
+         * Rebuilds the elements related to this component in case of
+         * context lost for instance.
+         */
+        OutlineRenderer.prototype.rebuild = function () {
+            // Nothing to do here.
+        };
+        /**
+         * Disposes the component and the associated ressources.
+         */
+        OutlineRenderer.prototype.dispose = function () {
+            // Nothing to do here.
+        };
+        /**
+         * Renders the outline in the canvas.
+         * @param subMesh Defines the sumesh to render
+         * @param batch Defines the batch of meshes in case of instances
+         * @param useOverlay Defines if the rendering is for the overlay or the outline
+         */
         OutlineRenderer.prototype.render = function (subMesh, batch, useOverlay) {
             var _this = this;
             if (useOverlay === void 0) { useOverlay = false; }
-            var scene = this._scene;
-            var engine = this._scene.getEngine();
+            var scene = this.scene;
+            var engine = scene.getEngine();
             var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
             if (!this.isReady(subMesh, hardwareInstancedRendering)) {
                 return;
@@ -100368,6 +100531,13 @@ var BABYLON;
             mesh._processRendering(subMesh, this._effect, BABYLON.Material.TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { _this._effect.setMatrix("world", world); });
             engine.setZOffset(0);
         };
+        /**
+         * Returns whether or not the outline renderer is ready for a given submesh.
+         * All the dependencies e.g. submeshes, texture, effect... mus be ready
+         * @param subMesh Defines the submesh to check readyness for
+         * @param useInstances Defines wheter wee are trying to render instances or not
+         * @returns true if ready otherwise false
+         */
         OutlineRenderer.prototype.isReady = function (subMesh, useInstances) {
             var defines = [];
             var attribs = [BABYLON.VertexBuffer.PositionKind, BABYLON.VertexBuffer.NormalKind];
@@ -100417,10 +100587,35 @@ var BABYLON;
             var join = defines.join("\n");
             if (this._cachedDefines !== join) {
                 this._cachedDefines = join;
-                this._effect = this._scene.getEngine().createEffect("outline", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "offset", "color", "logarithmicDepthConstant"], ["diffuseSampler"], join);
+                this._effect = this.scene.getEngine().createEffect("outline", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "offset", "color", "logarithmicDepthConstant"], ["diffuseSampler"], join);
             }
             return this._effect.isReady();
         };
+        OutlineRenderer.prototype._beforeRenderingMesh = function (mesh, subMesh, batch) {
+            // Outline - step 1
+            this._savedDepthWrite = this._engine.getDepthWrite();
+            if (mesh.renderOutline) {
+                this._engine.setDepthWrite(false);
+                this.render(subMesh, batch);
+                this._engine.setDepthWrite(this._savedDepthWrite);
+            }
+        };
+        OutlineRenderer.prototype._afterRenderingMesh = function (mesh, subMesh, batch) {
+            // Outline - step 2
+            if (mesh.renderOutline && this._savedDepthWrite) {
+                this._engine.setDepthWrite(true);
+                this._engine.setColorWrite(false);
+                this.render(subMesh, batch);
+                this._engine.setColorWrite(true);
+            }
+            // Overlay
+            if (mesh.renderOverlay) {
+                var currentMode = this._engine.getAlphaMode();
+                this._engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
+                this.render(subMesh, batch, true);
+                this._engine.setAlphaMode(currentMode);
+            }
+        };
         return OutlineRenderer;
     }());
     BABYLON.OutlineRenderer = OutlineRenderer;

+ 242 - 47
dist/preview release/babylon.no-module.max.js

@@ -19614,20 +19614,10 @@ var BABYLON;
              */
             _this.renderingGroupId = 0;
             _this._receiveShadows = false;
-            /**
-             * Gets or sets a boolean indicating if the outline must be rendered as well
-             * @see https://www.babylonjs-playground.com/#10WJ5S#3
-             */
-            _this.renderOutline = false;
             /** Defines color to use when rendering outline */
             _this.outlineColor = BABYLON.Color3.Red();
             /** Define width to use when rendering outline */
             _this.outlineWidth = 0.02;
-            /**
-             * Gets or sets a boolean indicating if the overlay must be rendered as well
-             * @see https://www.babylonjs-playground.com/#10WJ5S#2
-             */
-            _this.renderOverlay = false;
             /** Defines color to use when rendering overlay */
             _this.overlayColor = BABYLON.Color3.Red();
             /** Defines alpha to use when rendering overlay */
@@ -23703,6 +23693,7 @@ var BABYLON;
         SceneComponentConstants.NAME_DEPTHRENDERER = "DepthRenderer";
         SceneComponentConstants.NAME_POSTPROCESSRENDERPIPELINEMANAGER = "PostProcessRenderPipelineManager";
         SceneComponentConstants.NAME_SPRITE = "Sprite";
+        SceneComponentConstants.NAME_OUTLINERENDERER = "Outline";
         SceneComponentConstants.STEP_ISREADYFORMESH_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER = 0;
         SceneComponentConstants.STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER = 0;
@@ -23710,6 +23701,8 @@ var BABYLON;
         SceneComponentConstants.STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER = 1;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER = 1;
+        SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE = 0;
+        SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE = 0;
         SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE = 0;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_GAMEPAD = 1;
@@ -24453,11 +24446,22 @@ var BABYLON;
              */
             _this._beforeCameraDrawStage = BABYLON.Stage.Create();
             /**
+             * @hidden
              * Defines the actions happening just before a rendering group is drawing.
              */
             _this._beforeRenderingGroupDrawStage = BABYLON.Stage.Create();
             /**
              * @hidden
+             * Defines the actions happening just before a mesh is drawing.
+             */
+            _this._beforeRenderingMeshStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
+             * Defines the actions happening just after a mesh has been drawn.
+             */
+            _this._afterRenderingMeshStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
              * Defines the actions happening just after a rendering group has been drawn.
              */
             _this._afterRenderingGroupDrawStage = BABYLON.Stage.Create();
@@ -24499,9 +24503,6 @@ var BABYLON;
             if (BABYLON.PostProcessManager) {
                 _this.postProcessManager = new BABYLON.PostProcessManager(_this);
             }
-            if (BABYLON.OutlineRenderer) {
-                _this._outlineRenderer = new BABYLON.OutlineRenderer(_this);
-            }
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 _this.attachControl();
             }
@@ -25018,13 +25019,6 @@ var BABYLON;
             return this._cachedEffect !== effect || this._cachedMaterial !== material || this._cachedVisibility !== visibility;
         };
         /**
-         * Gets the outline renderer associated with the scene
-         * @returns a OutlineRenderer
-         */
-        Scene.prototype.getOutlineRenderer = function () {
-            return this._outlineRenderer;
-        };
-        /**
          * Gets the engine associated with the scene
          * @returns an Engine
          */
@@ -28092,6 +28086,8 @@ var BABYLON;
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
+            this._beforeRenderingMeshStage.clear();
+            this._afterRenderingMeshStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
             this._beforeCameraUpdateStage.clear();
@@ -32358,12 +32354,9 @@ var BABYLON;
             if (enableAlphaMode) {
                 engine.setAlphaMode(this._effectiveMaterial.alphaMode);
             }
-            // Outline - step 1
-            var savedDepthWrite = engine.getDepthWrite();
-            if (this.renderOutline) {
-                engine.setDepthWrite(false);
-                scene.getOutlineRenderer().render(subMesh, batch);
-                engine.setDepthWrite(savedDepthWrite);
+            for (var _i = 0, _a = scene._beforeRenderingMeshStage; _i < _a.length; _i++) {
+                var step = _a[_i];
+                step.action(this, subMesh, batch);
             }
             var effect;
             if (this._effectiveMaterial.storeEffectOnSubMeshes) {
@@ -32407,19 +32400,9 @@ var BABYLON;
             this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, this._effectiveMaterial);
             // Unbind
             this._effectiveMaterial.unbind();
-            // Outline - step 2
-            if (this.renderOutline && savedDepthWrite) {
-                engine.setDepthWrite(true);
-                engine.setColorWrite(false);
-                scene.getOutlineRenderer().render(subMesh, batch);
-                engine.setColorWrite(true);
-            }
-            // Overlay
-            if (this.renderOverlay) {
-                var currentMode = engine.getAlphaMode();
-                engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
-                scene.getOutlineRenderer().render(subMesh, batch, true);
-                engine.setAlphaMode(currentMode);
+            for (var _b = 0, _c = scene._afterRenderingMeshStage; _b < _c.length; _b++) {
+                var step = _c[_b];
+                step.action(this, subMesh, batch);
             }
             if (this._onAfterRenderObservable) {
                 this._onAfterRenderObservable.notifyObservers(this);
@@ -56134,6 +56117,7 @@ var BABYLON;
             this._limitVelocityGradients = null;
             this._dragGradients = null;
             this._emitRateGradients = null;
+            this._startSizeGradients = null;
             /** Gets or sets a value indicating the damping to apply if the limit velocity factor is reached */
             this.limitVelocityDamping = 0.4;
             /**
@@ -56246,6 +56230,14 @@ var BABYLON;
             return this._velocityGradients;
         };
         /**
+         * Gets the current list of start size gradients.
+         * You must use addStartSizeGradient and removeStartSizeGradient to udpate this list
+         * @returns the list of start size gradients
+         */
+        BaseParticleSystem.prototype.getStartSizeGradients = function () {
+            return this._startSizeGradients;
+        };
+        /**
          * Gets the current list of emit rate gradients.
          * You must use addEmitRateGradient and removeEmitRateGradient to udpate this list
          * @returns the list of emit rate gradients
@@ -56554,6 +56546,10 @@ var BABYLON;
             _this._currentEmitRate1 = 0;
             /** @hidden */
             _this._currentEmitRate2 = 0;
+            /** @hidden */
+            _this._currentStartSize1 = 0;
+            /** @hidden */
+            _this._currentStartSize2 = 0;
             // 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.
@@ -56964,6 +56960,37 @@ var BABYLON;
             return this;
         };
         /**
+         * Adds a new start size gradient (please note that this will only work if you set the targetStopDuration property)
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the start size value to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.addStartSizeGradient = function (gradient, factor, factor2) {
+            if (!this._startSizeGradients) {
+                this._startSizeGradients = [];
+            }
+            this._addFactorGradient(this._startSizeGradients, gradient, factor, factor2);
+            if (!this._currentStartSizeGradient) {
+                this._currentStartSizeGradient = this._startSizeGradients[0];
+                this._currentStartSize1 = this._currentStartSizeGradient.getFactor();
+                this._currentStartSize2 = this._currentStartSize1;
+            }
+            if (this._startSizeGradients.length === 2) {
+                this._currentStartSize2 = this._startSizeGradients[1].getFactor();
+            }
+            return this;
+        };
+        /**
+         * Remove a specific start size gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.removeStartSizeGradient = function (gradient) {
+            this._removeFactorGradient(this._emitRateGradients, gradient);
+            return this;
+        };
+        /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
          * @param color defines the color to affect to the specified gradient
@@ -57223,6 +57250,7 @@ var BABYLON;
         };
         // End of sub system methods
         ParticleSystem.prototype._update = function (newParticles) {
+            var _this = this;
             // Update current
             this._alive = this._particles.length > 0;
             if (this.emitter.position) {
@@ -57300,6 +57328,19 @@ var BABYLON;
                 }
                 // Size and scale
                 particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this_1.minScaleX, this_1.maxScaleX), BABYLON.Scalar.RandomRange(this_1.minScaleY, this_1.maxScaleY));
+                // Adjust scale by start size
+                if (this_1._startSizeGradients && this_1._startSizeGradients[0]) {
+                    var ratio = this_1._actualFrame / this_1.targetStopDuration;
+                    BABYLON.Tools.GetCurrentGradient(ratio, this_1._startSizeGradients, function (currentGradient, nextGradient, scale) {
+                        if (currentGradient !== _this._currentStartSizeGradient) {
+                            _this._currentStartSize1 = _this._currentStartSize2;
+                            _this._currentStartSize2 = nextGradient.getFactor();
+                            _this._currentStartSizeGradient = currentGradient;
+                        }
+                        var value = BABYLON.Scalar.Lerp(_this._currentStartSize1, _this._currentStartSize2, scale);
+                        particle.scale.scaleInPlace(value);
+                    });
+                }
                 // Angle
                 if (!this_1._angularSpeedGradients || this_1._angularSpeedGradients.length === 0) {
                     particle.angularSpeed = BABYLON.Scalar.RandomRange(this_1.minAngularSpeed, this_1.maxAngularSpeed);
@@ -57863,11 +57904,26 @@ var BABYLON;
                     serializationObject.emitRateGradients.push(serializedGradient);
                 }
             }
+            var startSizeGradients = particleSystem.getStartSizeGradients();
+            if (startSizeGradients) {
+                serializationObject.startSizeGradients = [];
+                for (var _f = 0, startSizeGradients_1 = startSizeGradients; _f < startSizeGradients_1.length; _f++) {
+                    var startSizeGradient = startSizeGradients_1[_f];
+                    var serializedGradient = {
+                        gradient: startSizeGradient.gradient,
+                        factor1: startSizeGradient.factor1
+                    };
+                    if (startSizeGradient.factor2 !== undefined) {
+                        serializedGradient.factor2 = startSizeGradient.factor2;
+                    }
+                    serializationObject.startSizeGradients.push(serializedGradient);
+                }
+            }
             var limitVelocityGradients = particleSystem.getLimitVelocityGradients();
             if (limitVelocityGradients) {
                 serializationObject.limitVelocityGradients = [];
-                for (var _f = 0, limitVelocityGradients_1 = limitVelocityGradients; _f < limitVelocityGradients_1.length; _f++) {
-                    var limitVelocityGradient = limitVelocityGradients_1[_f];
+                for (var _g = 0, limitVelocityGradients_1 = limitVelocityGradients; _g < limitVelocityGradients_1.length; _g++) {
+                    var limitVelocityGradient = limitVelocityGradients_1[_g];
                     var serializedGradient = {
                         gradient: limitVelocityGradient.gradient,
                         factor1: limitVelocityGradient.factor1
@@ -57988,9 +58044,15 @@ var BABYLON;
                     particleSystem.addEmitRateGradient(emitRateGradient.gradient, emitRateGradient.factor1 !== undefined ? emitRateGradient.factor1 : emitRateGradient.factor, emitRateGradient.factor2);
                 }
             }
+            if (parsedParticleSystem.startSizeGradients) {
+                for (var _m = 0, _o = parsedParticleSystem.startSizeGradients; _m < _o.length; _m++) {
+                    var startSizeGradient = _o[_m];
+                    particleSystem.addStartSizeGradient(startSizeGradient.gradient, startSizeGradient.factor1 !== undefined ? startSizeGradient.factor1 : startSizeGradient.factor, startSizeGradient.factor2);
+                }
+            }
             if (parsedParticleSystem.limitVelocityGradients) {
-                for (var _m = 0, _o = parsedParticleSystem.limitVelocityGradients; _m < _o.length; _m++) {
-                    var limitVelocityGradient = _o[_m];
+                for (var _p = 0, _q = parsedParticleSystem.limitVelocityGradients; _p < _q.length; _p++) {
+                    var limitVelocityGradient = _q[_p];
                     particleSystem.addLimitVelocityGradient(limitVelocityGradient.gradient, limitVelocityGradient.factor1 !== undefined ? limitVelocityGradient.factor1 : limitVelocityGradient.factor, limitVelocityGradient.factor2);
                 }
                 particleSystem.limitVelocityDamping = parsedParticleSystem.limitVelocityDamping;
@@ -61770,6 +61832,26 @@ var BABYLON;
             // Do nothing as emit rate is not supported by GPUParticleSystem
             return this;
         };
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the start size value to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.addStartSizeGradient = function (gradient, factor, factor2) {
+            // Do nothing as start size is not supported by GPUParticleSystem
+            return this;
+        };
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.removeStartSizeGradient = function (gradient) {
+            // Do nothing as start size is not supported by GPUParticleSystem
+            return this;
+        };
         GPUParticleSystem.prototype._reset = function () {
             this._releaseBuffers();
         };
@@ -100291,16 +100373,97 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * Gets the outline renderer associated with the scene
+     * @returns a OutlineRenderer
+     */
+    BABYLON.Scene.prototype.getOutlineRenderer = function () {
+        if (!this._outlineRenderer) {
+            this._outlineRenderer = new OutlineRenderer(this);
+        }
+        return this._outlineRenderer;
+    };
+    Object.defineProperty(BABYLON.AbstractMesh.prototype, "renderOutline", {
+        get: function () {
+            return this._renderOutline;
+        },
+        set: function (value) {
+            if (value) {
+                // Lazy Load the component.
+                this.getScene().getOutlineRenderer();
+            }
+            this._renderOutline = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BABYLON.AbstractMesh.prototype, "renderOverlay", {
+        get: function () {
+            return this._renderOverlay;
+        },
+        set: function (value) {
+            if (value) {
+                // Lazy Load the component.
+                this.getScene().getOutlineRenderer();
+            }
+            this._renderOverlay = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /**
+     * This class is responsible to draw bothe outline/overlay of meshes.
+     * It should not be used directly but through the available method on mesh.
+     */
     var OutlineRenderer = /** @class */ (function () {
+        /**
+         * Instantiates a new outline renderer. (There could be only one per scene).
+         * @param scene Defines the scene it belongs to
+         */
         function OutlineRenderer(scene) {
+            /**
+             * The name of the component. Each component must have a unique name.
+             */
+            this.name = BABYLON.SceneComponentConstants.NAME_OUTLINERENDERER;
+            /**
+             * Defines a zOffset to prevent zFighting between the overlay and the mesh.
+             */
             this.zOffset = 1;
-            this._scene = scene;
+            this.scene = scene;
+            this._engine = scene.getEngine();
+            this.scene._addComponent(this);
         }
+        /**
+         * Register the component to one instance of a scene.
+         */
+        OutlineRenderer.prototype.register = function () {
+            this.scene._beforeRenderingMeshStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE, this, this._beforeRenderingMesh);
+            this.scene._afterRenderingMeshStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE, this, this._afterRenderingMesh);
+        };
+        /**
+         * Rebuilds the elements related to this component in case of
+         * context lost for instance.
+         */
+        OutlineRenderer.prototype.rebuild = function () {
+            // Nothing to do here.
+        };
+        /**
+         * Disposes the component and the associated ressources.
+         */
+        OutlineRenderer.prototype.dispose = function () {
+            // Nothing to do here.
+        };
+        /**
+         * Renders the outline in the canvas.
+         * @param subMesh Defines the sumesh to render
+         * @param batch Defines the batch of meshes in case of instances
+         * @param useOverlay Defines if the rendering is for the overlay or the outline
+         */
         OutlineRenderer.prototype.render = function (subMesh, batch, useOverlay) {
             var _this = this;
             if (useOverlay === void 0) { useOverlay = false; }
-            var scene = this._scene;
-            var engine = this._scene.getEngine();
+            var scene = this.scene;
+            var engine = scene.getEngine();
             var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
             if (!this.isReady(subMesh, hardwareInstancedRendering)) {
                 return;
@@ -100335,6 +100498,13 @@ var BABYLON;
             mesh._processRendering(subMesh, this._effect, BABYLON.Material.TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { _this._effect.setMatrix("world", world); });
             engine.setZOffset(0);
         };
+        /**
+         * Returns whether or not the outline renderer is ready for a given submesh.
+         * All the dependencies e.g. submeshes, texture, effect... mus be ready
+         * @param subMesh Defines the submesh to check readyness for
+         * @param useInstances Defines wheter wee are trying to render instances or not
+         * @returns true if ready otherwise false
+         */
         OutlineRenderer.prototype.isReady = function (subMesh, useInstances) {
             var defines = [];
             var attribs = [BABYLON.VertexBuffer.PositionKind, BABYLON.VertexBuffer.NormalKind];
@@ -100384,10 +100554,35 @@ var BABYLON;
             var join = defines.join("\n");
             if (this._cachedDefines !== join) {
                 this._cachedDefines = join;
-                this._effect = this._scene.getEngine().createEffect("outline", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "offset", "color", "logarithmicDepthConstant"], ["diffuseSampler"], join);
+                this._effect = this.scene.getEngine().createEffect("outline", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "offset", "color", "logarithmicDepthConstant"], ["diffuseSampler"], join);
             }
             return this._effect.isReady();
         };
+        OutlineRenderer.prototype._beforeRenderingMesh = function (mesh, subMesh, batch) {
+            // Outline - step 1
+            this._savedDepthWrite = this._engine.getDepthWrite();
+            if (mesh.renderOutline) {
+                this._engine.setDepthWrite(false);
+                this.render(subMesh, batch);
+                this._engine.setDepthWrite(this._savedDepthWrite);
+            }
+        };
+        OutlineRenderer.prototype._afterRenderingMesh = function (mesh, subMesh, batch) {
+            // Outline - step 2
+            if (mesh.renderOutline && this._savedDepthWrite) {
+                this._engine.setDepthWrite(true);
+                this._engine.setColorWrite(false);
+                this.render(subMesh, batch);
+                this._engine.setColorWrite(true);
+            }
+            // Overlay
+            if (mesh.renderOverlay) {
+                var currentMode = this._engine.getAlphaMode();
+                this._engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
+                this.render(subMesh, batch, true);
+                this._engine.setAlphaMode(currentMode);
+            }
+        };
         return OutlineRenderer;
     }());
     BABYLON.OutlineRenderer = OutlineRenderer;

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 1
dist/preview release/babylon.worker.js


+ 242 - 47
dist/preview release/es6.js

@@ -19614,20 +19614,10 @@ var BABYLON;
              */
             _this.renderingGroupId = 0;
             _this._receiveShadows = false;
-            /**
-             * Gets or sets a boolean indicating if the outline must be rendered as well
-             * @see https://www.babylonjs-playground.com/#10WJ5S#3
-             */
-            _this.renderOutline = false;
             /** Defines color to use when rendering outline */
             _this.outlineColor = BABYLON.Color3.Red();
             /** Define width to use when rendering outline */
             _this.outlineWidth = 0.02;
-            /**
-             * Gets or sets a boolean indicating if the overlay must be rendered as well
-             * @see https://www.babylonjs-playground.com/#10WJ5S#2
-             */
-            _this.renderOverlay = false;
             /** Defines color to use when rendering overlay */
             _this.overlayColor = BABYLON.Color3.Red();
             /** Defines alpha to use when rendering overlay */
@@ -23703,6 +23693,7 @@ var BABYLON;
         SceneComponentConstants.NAME_DEPTHRENDERER = "DepthRenderer";
         SceneComponentConstants.NAME_POSTPROCESSRENDERPIPELINEMANAGER = "PostProcessRenderPipelineManager";
         SceneComponentConstants.NAME_SPRITE = "Sprite";
+        SceneComponentConstants.NAME_OUTLINERENDERER = "Outline";
         SceneComponentConstants.STEP_ISREADYFORMESH_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_BEFOREEVALUATEACTIVEMESH_BOUNDINGBOXRENDERER = 0;
         SceneComponentConstants.STEP_EVALUATESUBMESH_BOUNDINGBOXRENDERER = 0;
@@ -23710,6 +23701,8 @@ var BABYLON;
         SceneComponentConstants.STEP_CAMERADRAWRENDERTARGET_EFFECTLAYER = 1;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_EFFECTLAYER = 0;
         SceneComponentConstants.STEP_BEFORECAMERADRAW_LAYER = 1;
+        SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE = 0;
+        SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE = 0;
         SceneComponentConstants.STEP_AFTERRENDERINGGROUPDRAW_EFFECTLAYER_DRAW = 0;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_SIMPLIFICATIONQUEUE = 0;
         SceneComponentConstants.STEP_BEFORECAMERAUPDATE_GAMEPAD = 1;
@@ -24453,11 +24446,22 @@ var BABYLON;
              */
             _this._beforeCameraDrawStage = BABYLON.Stage.Create();
             /**
+             * @hidden
              * Defines the actions happening just before a rendering group is drawing.
              */
             _this._beforeRenderingGroupDrawStage = BABYLON.Stage.Create();
             /**
              * @hidden
+             * Defines the actions happening just before a mesh is drawing.
+             */
+            _this._beforeRenderingMeshStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
+             * Defines the actions happening just after a mesh has been drawn.
+             */
+            _this._afterRenderingMeshStage = BABYLON.Stage.Create();
+            /**
+             * @hidden
              * Defines the actions happening just after a rendering group has been drawn.
              */
             _this._afterRenderingGroupDrawStage = BABYLON.Stage.Create();
@@ -24499,9 +24503,6 @@ var BABYLON;
             if (BABYLON.PostProcessManager) {
                 _this.postProcessManager = new BABYLON.PostProcessManager(_this);
             }
-            if (BABYLON.OutlineRenderer) {
-                _this._outlineRenderer = new BABYLON.OutlineRenderer(_this);
-            }
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 _this.attachControl();
             }
@@ -25018,13 +25019,6 @@ var BABYLON;
             return this._cachedEffect !== effect || this._cachedMaterial !== material || this._cachedVisibility !== visibility;
         };
         /**
-         * Gets the outline renderer associated with the scene
-         * @returns a OutlineRenderer
-         */
-        Scene.prototype.getOutlineRenderer = function () {
-            return this._outlineRenderer;
-        };
-        /**
          * Gets the engine associated with the scene
          * @returns an Engine
          */
@@ -28092,6 +28086,8 @@ var BABYLON;
             this._cameraDrawRenderTargetStage.clear();
             this._beforeCameraDrawStage.clear();
             this._beforeRenderingGroupDrawStage.clear();
+            this._beforeRenderingMeshStage.clear();
+            this._afterRenderingMeshStage.clear();
             this._afterRenderingGroupDrawStage.clear();
             this._afterCameraDrawStage.clear();
             this._beforeCameraUpdateStage.clear();
@@ -32358,12 +32354,9 @@ var BABYLON;
             if (enableAlphaMode) {
                 engine.setAlphaMode(this._effectiveMaterial.alphaMode);
             }
-            // Outline - step 1
-            var savedDepthWrite = engine.getDepthWrite();
-            if (this.renderOutline) {
-                engine.setDepthWrite(false);
-                scene.getOutlineRenderer().render(subMesh, batch);
-                engine.setDepthWrite(savedDepthWrite);
+            for (var _i = 0, _a = scene._beforeRenderingMeshStage; _i < _a.length; _i++) {
+                var step = _a[_i];
+                step.action(this, subMesh, batch);
             }
             var effect;
             if (this._effectiveMaterial.storeEffectOnSubMeshes) {
@@ -32407,19 +32400,9 @@ var BABYLON;
             this._processRendering(subMesh, effect, fillMode, batch, hardwareInstancedRendering, this._onBeforeDraw, this._effectiveMaterial);
             // Unbind
             this._effectiveMaterial.unbind();
-            // Outline - step 2
-            if (this.renderOutline && savedDepthWrite) {
-                engine.setDepthWrite(true);
-                engine.setColorWrite(false);
-                scene.getOutlineRenderer().render(subMesh, batch);
-                engine.setColorWrite(true);
-            }
-            // Overlay
-            if (this.renderOverlay) {
-                var currentMode = engine.getAlphaMode();
-                engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
-                scene.getOutlineRenderer().render(subMesh, batch, true);
-                engine.setAlphaMode(currentMode);
+            for (var _b = 0, _c = scene._afterRenderingMeshStage; _b < _c.length; _b++) {
+                var step = _c[_b];
+                step.action(this, subMesh, batch);
             }
             if (this._onAfterRenderObservable) {
                 this._onAfterRenderObservable.notifyObservers(this);
@@ -56134,6 +56117,7 @@ var BABYLON;
             this._limitVelocityGradients = null;
             this._dragGradients = null;
             this._emitRateGradients = null;
+            this._startSizeGradients = null;
             /** Gets or sets a value indicating the damping to apply if the limit velocity factor is reached */
             this.limitVelocityDamping = 0.4;
             /**
@@ -56246,6 +56230,14 @@ var BABYLON;
             return this._velocityGradients;
         };
         /**
+         * Gets the current list of start size gradients.
+         * You must use addStartSizeGradient and removeStartSizeGradient to udpate this list
+         * @returns the list of start size gradients
+         */
+        BaseParticleSystem.prototype.getStartSizeGradients = function () {
+            return this._startSizeGradients;
+        };
+        /**
          * Gets the current list of emit rate gradients.
          * You must use addEmitRateGradient and removeEmitRateGradient to udpate this list
          * @returns the list of emit rate gradients
@@ -56554,6 +56546,10 @@ var BABYLON;
             _this._currentEmitRate1 = 0;
             /** @hidden */
             _this._currentEmitRate2 = 0;
+            /** @hidden */
+            _this._currentStartSize1 = 0;
+            /** @hidden */
+            _this._currentStartSize2 = 0;
             // 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.
@@ -56964,6 +56960,37 @@ var BABYLON;
             return this;
         };
         /**
+         * Adds a new start size gradient (please note that this will only work if you set the targetStopDuration property)
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the start size value to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.addStartSizeGradient = function (gradient, factor, factor2) {
+            if (!this._startSizeGradients) {
+                this._startSizeGradients = [];
+            }
+            this._addFactorGradient(this._startSizeGradients, gradient, factor, factor2);
+            if (!this._currentStartSizeGradient) {
+                this._currentStartSizeGradient = this._startSizeGradients[0];
+                this._currentStartSize1 = this._currentStartSizeGradient.getFactor();
+                this._currentStartSize2 = this._currentStartSize1;
+            }
+            if (this._startSizeGradients.length === 2) {
+                this._currentStartSize2 = this._startSizeGradients[1].getFactor();
+            }
+            return this;
+        };
+        /**
+         * Remove a specific start size gradient
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        ParticleSystem.prototype.removeStartSizeGradient = function (gradient) {
+            this._removeFactorGradient(this._emitRateGradients, gradient);
+            return this;
+        };
+        /**
          * Adds a new color gradient
          * @param gradient defines the gradient to use (between 0 and 1)
          * @param color defines the color to affect to the specified gradient
@@ -57223,6 +57250,7 @@ var BABYLON;
         };
         // End of sub system methods
         ParticleSystem.prototype._update = function (newParticles) {
+            var _this = this;
             // Update current
             this._alive = this._particles.length > 0;
             if (this.emitter.position) {
@@ -57300,6 +57328,19 @@ var BABYLON;
                 }
                 // Size and scale
                 particle.scale.copyFromFloats(BABYLON.Scalar.RandomRange(this_1.minScaleX, this_1.maxScaleX), BABYLON.Scalar.RandomRange(this_1.minScaleY, this_1.maxScaleY));
+                // Adjust scale by start size
+                if (this_1._startSizeGradients && this_1._startSizeGradients[0]) {
+                    var ratio = this_1._actualFrame / this_1.targetStopDuration;
+                    BABYLON.Tools.GetCurrentGradient(ratio, this_1._startSizeGradients, function (currentGradient, nextGradient, scale) {
+                        if (currentGradient !== _this._currentStartSizeGradient) {
+                            _this._currentStartSize1 = _this._currentStartSize2;
+                            _this._currentStartSize2 = nextGradient.getFactor();
+                            _this._currentStartSizeGradient = currentGradient;
+                        }
+                        var value = BABYLON.Scalar.Lerp(_this._currentStartSize1, _this._currentStartSize2, scale);
+                        particle.scale.scaleInPlace(value);
+                    });
+                }
                 // Angle
                 if (!this_1._angularSpeedGradients || this_1._angularSpeedGradients.length === 0) {
                     particle.angularSpeed = BABYLON.Scalar.RandomRange(this_1.minAngularSpeed, this_1.maxAngularSpeed);
@@ -57863,11 +57904,26 @@ var BABYLON;
                     serializationObject.emitRateGradients.push(serializedGradient);
                 }
             }
+            var startSizeGradients = particleSystem.getStartSizeGradients();
+            if (startSizeGradients) {
+                serializationObject.startSizeGradients = [];
+                for (var _f = 0, startSizeGradients_1 = startSizeGradients; _f < startSizeGradients_1.length; _f++) {
+                    var startSizeGradient = startSizeGradients_1[_f];
+                    var serializedGradient = {
+                        gradient: startSizeGradient.gradient,
+                        factor1: startSizeGradient.factor1
+                    };
+                    if (startSizeGradient.factor2 !== undefined) {
+                        serializedGradient.factor2 = startSizeGradient.factor2;
+                    }
+                    serializationObject.startSizeGradients.push(serializedGradient);
+                }
+            }
             var limitVelocityGradients = particleSystem.getLimitVelocityGradients();
             if (limitVelocityGradients) {
                 serializationObject.limitVelocityGradients = [];
-                for (var _f = 0, limitVelocityGradients_1 = limitVelocityGradients; _f < limitVelocityGradients_1.length; _f++) {
-                    var limitVelocityGradient = limitVelocityGradients_1[_f];
+                for (var _g = 0, limitVelocityGradients_1 = limitVelocityGradients; _g < limitVelocityGradients_1.length; _g++) {
+                    var limitVelocityGradient = limitVelocityGradients_1[_g];
                     var serializedGradient = {
                         gradient: limitVelocityGradient.gradient,
                         factor1: limitVelocityGradient.factor1
@@ -57988,9 +58044,15 @@ var BABYLON;
                     particleSystem.addEmitRateGradient(emitRateGradient.gradient, emitRateGradient.factor1 !== undefined ? emitRateGradient.factor1 : emitRateGradient.factor, emitRateGradient.factor2);
                 }
             }
+            if (parsedParticleSystem.startSizeGradients) {
+                for (var _m = 0, _o = parsedParticleSystem.startSizeGradients; _m < _o.length; _m++) {
+                    var startSizeGradient = _o[_m];
+                    particleSystem.addStartSizeGradient(startSizeGradient.gradient, startSizeGradient.factor1 !== undefined ? startSizeGradient.factor1 : startSizeGradient.factor, startSizeGradient.factor2);
+                }
+            }
             if (parsedParticleSystem.limitVelocityGradients) {
-                for (var _m = 0, _o = parsedParticleSystem.limitVelocityGradients; _m < _o.length; _m++) {
-                    var limitVelocityGradient = _o[_m];
+                for (var _p = 0, _q = parsedParticleSystem.limitVelocityGradients; _p < _q.length; _p++) {
+                    var limitVelocityGradient = _q[_p];
                     particleSystem.addLimitVelocityGradient(limitVelocityGradient.gradient, limitVelocityGradient.factor1 !== undefined ? limitVelocityGradient.factor1 : limitVelocityGradient.factor, limitVelocityGradient.factor2);
                 }
                 particleSystem.limitVelocityDamping = parsedParticleSystem.limitVelocityDamping;
@@ -61770,6 +61832,26 @@ var BABYLON;
             // Do nothing as emit rate is not supported by GPUParticleSystem
             return this;
         };
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to use (between 0 and 1)
+         * @param factor defines the start size value to affect to the specified gradient
+         * @param factor2 defines an additional factor used to define a range ([factor, factor2]) with main value to pick the final value from
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.addStartSizeGradient = function (gradient, factor, factor2) {
+            // Do nothing as start size is not supported by GPUParticleSystem
+            return this;
+        };
+        /**
+         * Not supported by GPUParticleSystem
+         * @param gradient defines the gradient to remove
+         * @returns the current particle system
+         */
+        GPUParticleSystem.prototype.removeStartSizeGradient = function (gradient) {
+            // Do nothing as start size is not supported by GPUParticleSystem
+            return this;
+        };
         GPUParticleSystem.prototype._reset = function () {
             this._releaseBuffers();
         };
@@ -100291,16 +100373,97 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * Gets the outline renderer associated with the scene
+     * @returns a OutlineRenderer
+     */
+    BABYLON.Scene.prototype.getOutlineRenderer = function () {
+        if (!this._outlineRenderer) {
+            this._outlineRenderer = new OutlineRenderer(this);
+        }
+        return this._outlineRenderer;
+    };
+    Object.defineProperty(BABYLON.AbstractMesh.prototype, "renderOutline", {
+        get: function () {
+            return this._renderOutline;
+        },
+        set: function (value) {
+            if (value) {
+                // Lazy Load the component.
+                this.getScene().getOutlineRenderer();
+            }
+            this._renderOutline = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    Object.defineProperty(BABYLON.AbstractMesh.prototype, "renderOverlay", {
+        get: function () {
+            return this._renderOverlay;
+        },
+        set: function (value) {
+            if (value) {
+                // Lazy Load the component.
+                this.getScene().getOutlineRenderer();
+            }
+            this._renderOverlay = value;
+        },
+        enumerable: true,
+        configurable: true
+    });
+    /**
+     * This class is responsible to draw bothe outline/overlay of meshes.
+     * It should not be used directly but through the available method on mesh.
+     */
     var OutlineRenderer = /** @class */ (function () {
+        /**
+         * Instantiates a new outline renderer. (There could be only one per scene).
+         * @param scene Defines the scene it belongs to
+         */
         function OutlineRenderer(scene) {
+            /**
+             * The name of the component. Each component must have a unique name.
+             */
+            this.name = BABYLON.SceneComponentConstants.NAME_OUTLINERENDERER;
+            /**
+             * Defines a zOffset to prevent zFighting between the overlay and the mesh.
+             */
             this.zOffset = 1;
-            this._scene = scene;
+            this.scene = scene;
+            this._engine = scene.getEngine();
+            this.scene._addComponent(this);
         }
+        /**
+         * Register the component to one instance of a scene.
+         */
+        OutlineRenderer.prototype.register = function () {
+            this.scene._beforeRenderingMeshStage.registerStep(BABYLON.SceneComponentConstants.STEP_BEFORERENDERINGMESH_OUTLINE, this, this._beforeRenderingMesh);
+            this.scene._afterRenderingMeshStage.registerStep(BABYLON.SceneComponentConstants.STEP_AFTERRENDERINGMESH_OUTLINE, this, this._afterRenderingMesh);
+        };
+        /**
+         * Rebuilds the elements related to this component in case of
+         * context lost for instance.
+         */
+        OutlineRenderer.prototype.rebuild = function () {
+            // Nothing to do here.
+        };
+        /**
+         * Disposes the component and the associated ressources.
+         */
+        OutlineRenderer.prototype.dispose = function () {
+            // Nothing to do here.
+        };
+        /**
+         * Renders the outline in the canvas.
+         * @param subMesh Defines the sumesh to render
+         * @param batch Defines the batch of meshes in case of instances
+         * @param useOverlay Defines if the rendering is for the overlay or the outline
+         */
         OutlineRenderer.prototype.render = function (subMesh, batch, useOverlay) {
             var _this = this;
             if (useOverlay === void 0) { useOverlay = false; }
-            var scene = this._scene;
-            var engine = this._scene.getEngine();
+            var scene = this.scene;
+            var engine = scene.getEngine();
             var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
             if (!this.isReady(subMesh, hardwareInstancedRendering)) {
                 return;
@@ -100335,6 +100498,13 @@ var BABYLON;
             mesh._processRendering(subMesh, this._effect, BABYLON.Material.TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { _this._effect.setMatrix("world", world); });
             engine.setZOffset(0);
         };
+        /**
+         * Returns whether or not the outline renderer is ready for a given submesh.
+         * All the dependencies e.g. submeshes, texture, effect... mus be ready
+         * @param subMesh Defines the submesh to check readyness for
+         * @param useInstances Defines wheter wee are trying to render instances or not
+         * @returns true if ready otherwise false
+         */
         OutlineRenderer.prototype.isReady = function (subMesh, useInstances) {
             var defines = [];
             var attribs = [BABYLON.VertexBuffer.PositionKind, BABYLON.VertexBuffer.NormalKind];
@@ -100384,10 +100554,35 @@ var BABYLON;
             var join = defines.join("\n");
             if (this._cachedDefines !== join) {
                 this._cachedDefines = join;
-                this._effect = this._scene.getEngine().createEffect("outline", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "offset", "color", "logarithmicDepthConstant"], ["diffuseSampler"], join);
+                this._effect = this.scene.getEngine().createEffect("outline", attribs, ["world", "mBones", "viewProjection", "diffuseMatrix", "offset", "color", "logarithmicDepthConstant"], ["diffuseSampler"], join);
             }
             return this._effect.isReady();
         };
+        OutlineRenderer.prototype._beforeRenderingMesh = function (mesh, subMesh, batch) {
+            // Outline - step 1
+            this._savedDepthWrite = this._engine.getDepthWrite();
+            if (mesh.renderOutline) {
+                this._engine.setDepthWrite(false);
+                this.render(subMesh, batch);
+                this._engine.setDepthWrite(this._savedDepthWrite);
+            }
+        };
+        OutlineRenderer.prototype._afterRenderingMesh = function (mesh, subMesh, batch) {
+            // Outline - step 2
+            if (mesh.renderOutline && this._savedDepthWrite) {
+                this._engine.setDepthWrite(true);
+                this._engine.setColorWrite(false);
+                this.render(subMesh, batch);
+                this._engine.setColorWrite(true);
+            }
+            // Overlay
+            if (mesh.renderOverlay) {
+                var currentMode = this._engine.getAlphaMode();
+                this._engine.setAlphaMode(BABYLON.Engine.ALPHA_COMBINE);
+                this.render(subMesh, batch, true);
+                this._engine.setAlphaMode(currentMode);
+            }
+        };
         return OutlineRenderer;
     }());
     BABYLON.OutlineRenderer = OutlineRenderer;

+ 19 - 5
dist/preview release/viewer/babylon.viewer.d.ts

@@ -168,11 +168,11 @@ declare module BabylonViewer {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
+            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<string> | Promise<Template>;
+            hideOverlayScreen(): Promise<Template> | Promise<string>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -189,11 +189,11 @@ declare module BabylonViewer {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<string> | Promise<Template>;
+            showLoadingScreen(): Promise<Template> | Promise<string>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<string> | Promise<Template>;
+            hideLoadingScreen(): Promise<Template> | Promise<string>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
@@ -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 {

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 22 - 5
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -200,11 +200,11 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Mainly used for help and errors
                 * @param subScreen the name of the subScreen. Those can be defined in the configuration object
                 */
-            showOverlayScreen(subScreen: string): Promise<string> | Promise<Template>;
+            showOverlayScreen(subScreen: string): Promise<Template> | Promise<string>;
             /**
                 * Hide the overlay screen.
                 */
-            hideOverlayScreen(): Promise<string> | Promise<Template>;
+            hideOverlayScreen(): Promise<Template> | Promise<string>;
             /**
                 * show the viewer (in case it was hidden)
                 *
@@ -221,11 +221,11 @@ declare module 'babylonjs-viewer/viewer/defaultViewer' {
                 * Show the loading screen.
                 * The loading screen can be configured using the configuration object
                 */
-            showLoadingScreen(): Promise<string> | Promise<Template>;
+            showLoadingScreen(): Promise<Template> | Promise<string>;
             /**
                 * Hide the loading screen
                 */
-            hideLoadingScreen(): Promise<string> | Promise<Template>;
+            hideLoadingScreen(): Promise<Template> | Promise<string>;
             dispose(): void;
             protected _onConfigurationLoaded(configuration: ViewerConfiguration): void;
     }
@@ -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';