using System.Diagnostics;
using LibNoise.Generator;
namespace LibNoise.Operator
{
///
/// Provides a noise module that that randomly displaces the input value before
/// returning the output value from a source module. [OPERATOR]
///
public class Turbulence : ModuleBase
{
#region Constants
private const double X0 = (12414.0 / 65536.0);
private const double Y0 = (65124.0 / 65536.0);
private const double Z0 = (31337.0 / 65536.0);
private const double X1 = (26519.0 / 65536.0);
private const double Y1 = (18128.0 / 65536.0);
private const double Z1 = (60493.0 / 65536.0);
private const double X2 = (53820.0 / 65536.0);
private const double Y2 = (11213.0 / 65536.0);
private const double Z2 = (44845.0 / 65536.0);
#endregion
#region Fields
private double _power = 1.0;
private readonly Perlin _xDistort;
private readonly Perlin _yDistort;
private readonly Perlin _zDistort;
#endregion
#region Constructors
///
/// Initializes a new instance of Turbulence.
///
public Turbulence()
: base(1)
{
_xDistort = new Perlin();
_yDistort = new Perlin();
_zDistort = new Perlin();
}
///
/// Initializes a new instance of Turbulence.
///
/// The input module.
public Turbulence(ModuleBase input)
: base(1)
{
_xDistort = new Perlin();
_yDistort = new Perlin();
_zDistort = new Perlin();
Modules[0] = input;
}
///
/// Initializes a new instance of Turbulence.
///
public Turbulence(double power, ModuleBase input)
: this(new Perlin(), new Perlin(), new Perlin(), power, input)
{
}
///
/// Initializes a new instance of Turbulence.
///
/// The perlin noise to apply on the x-axis.
/// The perlin noise to apply on the y-axis.
/// The perlin noise to apply on the z-axis.
/// The power of the turbulence.
/// The input module.
public Turbulence(Perlin x, Perlin y, Perlin z, double power, ModuleBase input)
: base(1)
{
_xDistort = x;
_yDistort = y;
_zDistort = z;
Modules[0] = input;
Power = power;
}
#endregion
#region Properties
///
/// Gets or sets the frequency of the turbulence.
///
public double Frequency
{
get { return _xDistort.Frequency; }
set
{
_xDistort.Frequency = value;
_yDistort.Frequency = value;
_zDistort.Frequency = value;
}
}
///
/// Gets or sets the power of the turbulence.
///
public double Power
{
get { return _power; }
set { _power = value; }
}
///
/// Gets or sets the roughness of the turbulence.
///
public int Roughness
{
get { return _xDistort.OctaveCount; }
set
{
_xDistort.OctaveCount = value;
_yDistort.OctaveCount = value;
_zDistort.OctaveCount = value;
}
}
///
/// Gets or sets the seed of the turbulence.
///
public int Seed
{
get { return _xDistort.Seed; }
set
{
_xDistort.Seed = value;
_yDistort.Seed = value + 1;
_zDistort.Seed = value + 2;
}
}
#endregion
#region ModuleBase Members
///
/// Returns the output value for the given input coordinates.
///
/// The input coordinate on the x-axis.
/// The input coordinate on the y-axis.
/// The input coordinate on the z-axis.
/// The resulting output value.
public override double GetValue(double x, double y, double z)
{
Debug.Assert(Modules[0] != null);
var xd = x + (_xDistort.GetValue(x + X0, y + Y0, z + Z0) * _power);
var yd = y + (_yDistort.GetValue(x + X1, y + Y1, z + Z1) * _power);
var zd = z + (_zDistort.GetValue(x + X2, y + Y2, z + Z2) * _power);
return Modules[0].GetValue(xd, yd, zd);
}
#endregion
}
}