FastSin() public static method

Calculates the approximate value of sine function at a given angle.
This function is much faster than Mathf.Sin(), especially on mobile devices.
public static FastSin ( float x ) : float
x float /// The angle in radians. ///
return float
    /// <summary>
    /// Executes the simulation step.
    /// </summary>
    /// <param name="speed">
    /// The overall simulation speed factor.
    /// </param>
    /// <param name="damping">
    /// The damping value (range 0-1).
    /// </param>
    public override void StepSimulation(float speed, float damping)
    {
        if (!OnlyAmbient)
        {
            base.StepSimulation(speed, damping);
        }

        _canInteract = !OnlyAmbient;

        bool isFieldObstructionNull = _fieldObstruction == null;

        // Ambient wave time
        _time += Time.deltaTime * AmbientWaveSpeed;

        // Caching to avoid many divisions
        Vector2 invGrid = new Vector2(1f / _grid.x, 1f / _grid.y);

        for (int i = 0; i < _grid.x; i++)
        {
            for (int j = 0; j < _grid.y; j++)
            {
                int index = j * _grid.x + i;
                if (!isFieldObstructionNull && _fieldObstruction[index] == byte.MinValue)
                {
                    continue;
                }
                // Obstruction value (0-1) determined by obstruction geometry and obstruction mask
                float obstructionValue = isFieldObstructionNull ? 1f : _fieldObstruction[index] * FastFunctions.InvertedByteMaxValue;

                // Normalizing the coordinates
                float normX = i * invGrid.x;
                float normY = j * invGrid.y;

                // Calculating new node value
                float val = (normX + normY) * FastFunctions.DoublePi;
                if (OnlyAmbient)
                {
                    _fieldSum[index] = FastFunctions.FastSin(val * AmbientWaveFrequency + _time) * AmbientWaveHeight * obstructionValue;
                }
                else
                {
                    _fieldSum[index] = FastFunctions.FastSin(val * AmbientWaveFrequency + _time) * AmbientWaveHeight * obstructionValue + FieldSimNew[index];
                }
            }
        }

        // Updating the field
        _field = _fieldSum;

        _isDirty = true;
    }
    /// <summary>
    /// Executes the simulation step.
    /// </summary>
    /// <param name="speed">
    /// The overall simulation speed factor.
    /// </param>
    /// <param name="damping">
    /// The damping value (range 0-1).
    /// </param>
    public override void StepSimulation(float speed, float damping)
    {
        if (!OnlyAmbient)
        {
            base.StepSimulation(speed, damping);
        }

        _canInteract = !OnlyAmbient;
        bool isFieldObstructionNull = _fieldObstruction == null;

        // Ambient wave time
        _time += Time.deltaTime;

        // Recalculating direction
        foreach (Wave wave in Waves)
        {
            wave.Direction   = new Vector2(FastFunctions.FastCos(wave.Angle * FastFunctions.Deg2Rad), FastFunctions.FastSin(wave.Angle * FastFunctions.Deg2Rad));
            wave.CircleShift = new Vector2(-Mathf.Clamp01(wave.Position.x) * FastFunctions.DoublePi, -Mathf.Clamp01(wave.Position.y) * FastFunctions.DoublePi);
        }

        // Caching to avoid many divisions
        Vector2 invGrid = new Vector2(1f / _grid.x, 1f / _grid.y);

        for (int i = 0; i < _grid.x; i++)
        {
            for (int j = 0; j < _grid.y; j++)
            {
                int index = j * _grid.x + i;

                if (!isFieldObstructionNull && _fieldObstruction[index] == byte.MinValue)
                {
                    continue;
                }
                // Obstruction value (0-1) determined by obstruction geometry and obstruction mask
                float obstructionValue = isFieldObstructionNull ? 1f : _fieldObstruction[index] * FastFunctions.InvertedByteMaxValue;

                // Normalizing the coordinates
                float normX = i * invGrid.x * FastFunctions.DoublePi;
                float normY = j * invGrid.y * FastFunctions.DoublePi;
                _fieldSum[index] = 0f;
                for (int k = 0; k < Waves.Length; k++)
                {
                    Wave wave = Waves[k];
                    // Calculating new node value
                    if (wave.Excluded)
                    {
                        continue;
                    }

                    float val;
                    if (wave.Circular)
                    {
                        normX += wave.CircleShift.x;
                        normY += wave.CircleShift.y;
                        /* Non-optimized version. Use it if you want */
                        //val = FastFunctions.FastSqrt(normX * normX + normY * normY) * wave.Frequency + _time * wave.Velocity;

                        val = normX * normX + normY * normY;

                        FastFunctions.FloatIntUnion u;
                        u.i = 0;
                        u.f = val;
                        float xhalf = 0.5f * val;
                        u.i = 0x5f375a86 - (u.i >> 1);
                        u.f = u.f * (1.5f - xhalf * u.f * u.f);

                        val = u.f * val * wave.Frequency + _time * wave.Velocity;
                    }
                    else
                    {
                        val = (wave.Direction.x * normX + wave.Direction.y * normY) * wave.Frequency + _time * wave.Velocity;
                    }

                    /* Non-optimized version. Use it if you want */
                    //_fieldSum[index] += FastFunctions.FastPow((FastFunctions.FastSin(val) + 1f) * 0.5f, wave.Steepness) * wave.Amplitude * obstructionValue;

                    /* Optimized version */
                    // FastFunctions.FastSin(val)
                    float tmpVal = (val + Mathf.PI) * FastFunctions.InvDoublePi;
                    int   floor  = tmpVal >= 0 ? (int)(tmpVal) : (int)((tmpVal) - 1);
                    val = val - FastFunctions.DoublePi * floor;

                    if (val < 0)
                    {
                        val = 1.27323954f * val + 0.405284735f * val * val;
                    }
                    else
                    {
                        val = 1.27323954f * val - 0.405284735f * val * val;
                    }

                    // FastFunctions.FastPowInt
                    tmpVal = (val + 1f) * 0.5f;
                    int steepness = wave.Steepness;

                    while (steepness > 0)
                    {
                        tmpVal *= val;
                        steepness--;
                    }

                    // Final calculations
                    val = tmpVal * wave.Amplitude * obstructionValue;
                    _fieldSum[index] += val;

                    /* End of optimized version */
                }

                if (!OnlyAmbient)
                {
                    _fieldSum[index] += FieldSimNew[index];
                }
            }
        }

        // Updating the field
        _field = _fieldSum;

        _isDirty = true;
    }