using System; using System.Collections.Generic; using System.Linq; using System.Text; using UnityEngine; using TransportGame.Utils; namespace TransportGame.Noise { public abstract class NoiseGenerator { public float Scale { get; set; } public float Low { get; set; } public float High { get; set; } public float NonLinearPower { get; set; } public int Octaves { get; set; } public float Persistence { get; set; } private float seedX, seedY; public NoiseGenerator() { System.Random random = new System.Random(); seedX = random.NextSingle(-10000f, 10000f); seedY = random.NextSingle(-10000f, 10000f); Scale = 1f; Low = -1f; High = 1f; NonLinearPower = 1f; Octaves = 1; Persistence = .5f; } /// /// Produces noise in the [-1,1] interval /// /// /// /// protected abstract float GenerateNoise(float x, float y); /// /// Generates noise /// /// X coordinate /// Y coordinate /// Minimum value /// Maximum value /// Scale /// Number of octaves (layers) /// Persistence (impact of each layer) /// Non-linearity /// Noise public float Generate(float x, float y, float low, float high, float scale, int octaves, float persistence, float nonLinearPower) { float value = 0; int freq = 1; float amp = 1; float maxAmp = 0; for (int i = 0; i < octaves; ++i) { value += GenerateNoise(seedX + freq * scale * x, seedY + freq * scale * y) * amp; maxAmp += amp; amp *= persistence; freq *= 2; } // Bring to [0,1] value = (value / maxAmp) / 2f + .5f; // Raise to non-linear power value = Mathf.Pow(value, nonLinearPower); // Bring to required interval value = value * (high - low) + low; // Done return value; } /// /// Generates noise /// /// X coordinate /// Y coordinate /// Minimum value /// Maximum value /// Scale /// Number of octaves (layers) /// Persistence (impact of each layer) /// Noise public float Generate(float x, float y, float low, float high, float scale, int octaves, float persistence) { return Generate(x, y, low, high, scale, octaves, persistence, NonLinearPower); } /// /// Generates noise /// /// X coordinate /// Y coordinate /// Minimum value /// Maximum value /// Scale /// Noise public float Generate(float x, float y, float low, float high, float scale) { return Generate(x, y, low, high, scale, Octaves, Persistence, NonLinearPower); } /// /// Generates noise /// /// X coordinate /// Y coordinate /// Minimum value /// Maximum value /// Noise public float Generate(float x, float y, float low, float high) { return Generate(x, y, low, high, Scale, Octaves, Persistence, NonLinearPower); } /// /// Generates noise /// /// X coordinate /// Y coordinate /// Noise public float Generate(float x, float y) { return Generate(x, y, Low, High, Scale, Octaves, Persistence, NonLinearPower); } } }