Nez.Portable/ECS/Components/Renderables/Particles/Particle.cs
/// <summary>
/// updates the particle. Returns true when the particle is no longer alive
/// </summary>
/// <param name="emitterConfig">Emitter config.</param>
updates the particle. Returns true when the particle is no longer alive
updates the particle . Returns true when the particle is no longer alive
public bool update(
            ParticleEmitterConfig emitterConfig,
            ref ParticleCollisionConfig collisionConfig,
            Vector2 rootPosition)
        {
            _timeToLive -= Time.deltaTime;
            if (_timeToLive > 0)
            {
                if (!_collided)
                {
                    if (emitterConfig.emitterType == ParticleEmitterType.Radial)
                    {
                        _angle += _degreesPerSecond * Time.deltaTime;
                        _radius += _radiusDelta * Time.deltaTime;
                        Vector2 tmp;
                        tmp.X = -Mathf.cos(_angle) * _radius;
                        tmp.Y = -Mathf.sin(_angle) * _radius;
                        _velocity = tmp - position;
                        position = tmp;
                    }
                    else
                    {
                        Vector2 tmp, radial, tangential;
                        radial = Vector2.Zero;
                        if (position.X != 0 || position.Y != 0)
                            Vector2.Normalize(ref position, out radial);
                        tangential = radial;
                        radial = radial * _radialAcceleration;
                        var newy = tangential.X;
                        tangential.X = -tangential.Y;
                        tangential.Y = newy;
                        tangential = tangential * _tangentialAcceleration;
                        tmp = radial + tangential + emitterConfig.gravity;
                        tmp = tmp * Time.deltaTime;
                        _direction = _direction + tmp;
                        tmp = _direction * Time.deltaTime;
                        _velocity = tmp / Time.deltaTime;
                        position = position + tmp;
                    }
                }
                var t = (_particleLifetime - _timeToLive) / _particleLifetime;
                ColorExt.lerp(ref _startColor, ref _finishColor, out color, t);
                particleSize += _particleSizeDelta * Time.deltaTime;
                particleSize = MathHelper.Max(0, particleSize);
                rotation += _rotationDelta * Time.deltaTime;
                if (collisionConfig.enabled)
                {
                    if (_collided)
                    {
                        _velocity += collisionConfig.gravity * Time.deltaTime;
                        position += _velocity * Time.deltaTime;
                        if (_velocity.LengthSquared() < collisionConfig.minKillSpeedSquared)
                            return true;
                    }
                    var pos = emitterConfig.simulateInWorldSpace ? spawnPosition : rootPosition;
                    _circleCollisionShape.recalculateBounds(
                        particleSize * 0.5f * collisionConfig.radiusScale,
                        pos + position);
                    var neighbors = Physics.boxcastBroadphase(
                        ref _circleCollisionShape.bounds,
                        collisionConfig.collidesWithLayers);
                    foreach (var neighbor in neighbors)
                    {
                        CollisionResult result;
                        if (_circleCollisionShape.collidesWithShape(neighbor.shape, out result))
                        {
                            position -= result.minimumTranslationVector;
                            calculateCollisionResponseVelocity(
                                collisionConfig.friction,
                                collisionConfig.elasticity,
                                ref result.minimumTranslationVector);
                            _timeToLive -= _timeToLive * collisionConfig.lifetimeLoss;
                            _collided = true;
                        }
                    }
                }
            }
            else
            {
                return true;
            }
            return false;
        }
public bool update ( ParticleEmitterConfig emitterConfig , ref ParticleCollisionConfig collisionConfig , Vector2 rootPosition ) { _timeToLive -= Time . deltaTime ; if ( _timeToLive > 0 ) { if ( ! _collided ) { if ( emitterConfig . emitterType == ParticleEmitterType . Radial ) { _angle += _degreesPerSecond * Time . deltaTime ; _radius += _radiusDelta * Time . deltaTime ; Vector2 tmp ; tmp . X = - Mathf . cos ( _angle ) * _radius ; tmp . Y = - Mathf . sin ( _angle ) * _radius ; _velocity = tmp - position ; position = tmp ; } else { Vector2 tmp , radial , tangential ; radial = Vector2 . Zero ; if ( position . X != 0 || position . Y != 0 ) Vector2 . Normalize ( ref position , out radial ) ; tangential = radial ; radial = radial * _radialAcceleration ; var newy = tangential . X ; tangential . X = - tangential . Y ; tangential . Y = newy ; tangential = tangential * _tangentialAcceleration ; tmp = radial + tangential + emitterConfig . gravity ; tmp = tmp * Time . deltaTime ; _direction = _direction + tmp ; tmp = _direction * Time . deltaTime ; _velocity = tmp / Time . deltaTime ; position = position + tmp ; } } var t = ( _particleLifetime - _timeToLive ) / _particleLifetime ; ColorExt . lerp ( ref _startColor , ref _finishColor , out color , t ) ; particleSize += _particleSizeDelta * Time . deltaTime ; particleSize = MathHelper . Max ( 0 , particleSize ) ; rotation += _rotationDelta * Time . deltaTime ; if ( collisionConfig . enabled ) { if ( _collided ) { _velocity += collisionConfig . gravity * Time . deltaTime ; position += _velocity * Time . deltaTime ; if ( _velocity . LengthSquared ( ) < collisionConfig . minKillSpeedSquared ) return true ; } var pos = emitterConfig . simulateInWorldSpace ? spawnPosition : rootPosition ; _circleCollisionShape . recalculateBounds ( particleSize * 0.5f * collisionConfig . radiusScale , pos + position ) ; var neighbors = Physics . boxcastBroadphase ( ref _circleCollisionShape . bounds , collisionConfig . collidesWithLayers ) ; foreach ( var neighbor in neighbors ) { CollisionResult result ; if ( _circleCollisionShape . collidesWithShape ( neighbor . shape , out result ) ) { position -= result . minimumTranslationVector ; calculateCollisionResponseVelocity ( collisionConfig . friction , collisionConfig . elasticity , ref result . minimumTranslationVector ) ; _timeToLive -= _timeToLive * collisionConfig . lifetimeLoss ; _collided = true ; } } } } else { return true ; } return false ; }
updates the particle.
updates the particle .
// PART 1: reduce the life span of the particle // if the current particle is alive then update it // only update the particle position if it has not collided. If it has, physics takes over // if maxRadius is greater than 0 then the particles are going to spin otherwise they are affected by speed and gravity // PART 2: update the angle of the particle from the radius. This is only done if the particles are rotating // update the particles color. we do the lerp from finish-to-start because timeToLive counts from particleLifespan to 0 // update the particle size // update the rotation of the particle // if we already collided we have to handle the collision response // handle after collision movement. we need to track velocity for this // if we move too slow we die // should we use our spawnPosition as a reference or the parent Transforms position? // handle the overlap // handle collision config props // timeToLive expired. were done
emitterConfig
ParticleEmitterConfig
None
ParticleCollisionConfig
ref
rootPosition
Vector2