/// <inheritdoc/>
        protected override void OnInitializeParticles(int startIndex, int count, object emitter)
        {
            if (_linearSpeedParameter == null ||
                _directionParameter == null ||
                _biasVelocityParameter == null)
            {
                return;
            }

            Vector3[] directions = _directionParameter.Values;
            float[]   speeds     = _linearSpeedParameter.Values;
            Vector3[] biases     = _biasVelocityParameter.Values;

            if (directions != null && speeds != null && biases != null)
            {
                // Optimized case: Direction, Speed, and Acceleration are varying parameters.
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    Vector3 velocity = directions[i] * speeds[i];
                    velocity += biases[i] * Strength;
                    speeds[i] = velocity.Length;
                    if (!Numeric.IsZero(speeds[i]))
                    {
                        directions[i] = velocity / speeds[i];
                    }
                }
            }
            else if (directions != null && speeds != null)
            {
                // Optimized case: Direction and Speed are varying parameters, Bias is uniform.
                Vector3 bias = _biasVelocityParameter.DefaultValue * Strength;
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    Vector3 velocity = directions[i] * speeds[i];
                    velocity += bias;
                    speeds[i] = velocity.Length;
                    if (!Numeric.IsZero(speeds[i]))
                    {
                        directions[i] = velocity / speeds[i];
                    }
                }
            }
            else if (directions != null || speeds != null)
            {
                // General case: Either Direction or Speed is varying parameter.
                // This path does not make sense much sense. - But maybe someone has an idea how to use it.
                Vector3 bias = _biasVelocityParameter.DefaultValue * Strength;
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    Vector3 velocity = _directionParameter.GetValue(i) * _linearSpeedParameter.GetValue(i);
                    velocity += bias;
                    var newSpeed = velocity.Length;
                    _linearSpeedParameter.SetValue(i, newSpeed);
                    if (!Numeric.IsZero(newSpeed))
                    {
                        _directionParameter.SetValue(i, velocity / newSpeed);
                    }
                }
            }
        }
Beispiel #2
0
        // This method is called each frame to update particles.
        protected override void OnUpdateParticles(TimeSpan deltaTime, int startIndex, int count)
        {
            // Abort if we are missing particle parameters.
            if (_positionParameter == null ||
                _linearSpeedParameter == null ||
                _directionParameter == null)
            {
                return;
            }

            // Get the direction and linear speed particle parameter arrays.
            for (int i = startIndex; i < startIndex + count; i++)
            {
                // Get the particle position and check if the position is behind the plane.
                Vector3 position = _positionParameter.GetValue(i);
                if (Vector3.Dot(position, _plane.Normal) > _plane.DistanceFromOrigin)
                {
                    continue;
                }

                // Get the linear velocity of the particle.
                Vector3 velocity = _directionParameter.GetValue(i) * _linearSpeedParameter.GetValue(i);

                // Check if the particle is moving into the plane or away.
                float normalSpeed = Vector3.Dot(velocity, _plane.Normal);
                if (normalSpeed > 0)
                {
                    continue;
                }

                // Get the restitution. If there is no restitution particle parameter, we use a default value.
                float restitution = (_restitutionParameter != null) ? _restitutionParameter.GetValue(i) : 0.5f;

                // Change the velocity to let the particle bounce off.
                velocity = velocity - (1 + restitution) * _plane.Normal * normalSpeed;

                // Update LinearSpeed and Direction from the velocity vector.
                // The speed is the magnitude of the velocity vector.
                var newSpeed = velocity.Length;
                _linearSpeedParameter.SetValue(i, newSpeed);

                // Direction stores the normalized direction of the velocity vector.
                if (!Numeric.IsZero(newSpeed))
                {
                    _directionParameter.SetValue(i, velocity / newSpeed);
                }
            }
        }
Beispiel #3
0
        /// <inheritdoc/>
        protected override void OnUpdateParticles(TimeSpan deltaTime, int startIndex, int count)
        {
            if (_linearSpeedParameter == null ||
                _directionParameter == null ||
                _linearAccelerationParameter == null)
            {
                return;
            }

            // Update varying parameters.
            Vector3[] directions    = _directionParameter.Values;
            float[]   speeds        = _linearSpeedParameter.Values;
            Vector3[] accelerations = _linearAccelerationParameter.Values;
            float     dt            = (float)deltaTime.TotalSeconds;

            if (directions != null && speeds != null && accelerations != null)
            {
                // Optimized case: Direction, Speed, and Acceleration are varying parameters.
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    Vector3 velocity = directions[i] * speeds[i];
                    velocity += accelerations[i] * dt;
                    speeds[i] = velocity.Length;
                    if (!Numeric.IsZero(speeds[i]))
                    {
                        directions[i] = velocity / speeds[i];
                    }
                }
            }
            else if (directions != null && speeds != null)
            {
                // Optimized case: Direction and Speed are varying parameters, Acceleration is uniform.
                Vector3 acceleration = _linearAccelerationParameter.DefaultValue;
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    Vector3 velocity = directions[i] * speeds[i];
                    velocity += acceleration * dt;
                    speeds[i] = velocity.Length;
                    if (!Numeric.IsZero(speeds[i]))
                    {
                        directions[i] = velocity / speeds[i];
                    }
                }
            }
            else if (directions != null || speeds != null)
            {
                // General case: Either Direction or Speed is varying parameter.
                // This path does not make sense much sense. - But maybe someone has an idea how to use it.
                Vector3 acceleration = _linearAccelerationParameter.DefaultValue;
                for (int i = startIndex; i < startIndex + count; i++)
                {
                    Vector3 velocity = _directionParameter.GetValue(i) * _linearSpeedParameter.GetValue(i);
                    velocity += acceleration * dt;
                    var newSpeed = velocity.Length;
                    _linearSpeedParameter.SetValue(i, newSpeed);
                    if (!Numeric.IsZero(newSpeed))
                    {
                        _directionParameter.SetValue(i, velocity / newSpeed);
                    }
                }
            }
        }