using System.Collections.Generic; using UnityEngine; using Debug = System.Diagnostics.Debug; namespace LibNoise.Operator { /// /// Provides a noise module that maps the output value from a source module onto an /// arbitrary function curve. [OPERATOR] /// public class Curve : ModuleBase { #region Fields private readonly List> _data = new List>(); #endregion #region Constructors /// /// Initializes a new instance of Curve. /// public Curve() : base(1) { } /// /// Initializes a new instance of Curve. /// /// The input module. public Curve(ModuleBase input) : base(1) { Modules[0] = input; } #endregion #region Properties /// /// Gets the number of control points. /// public int ControlPointCount { get { return _data.Count; } } /// /// Gets the list of control points. /// public List> ControlPoints { get { return _data; } } #endregion #region Methods /// /// Adds a control point to the curve. /// /// The curves input value. /// The curves output value. public void Add(double input, double output) { var kvp = new KeyValuePair(input, output); if (!_data.Contains(kvp)) { _data.Add(kvp); } _data.Sort( delegate(KeyValuePair lhs, KeyValuePair rhs) { return lhs.Key.CompareTo(rhs.Key); }); } /// /// Clears the control points. /// public void Clear() { _data.Clear(); } #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); Debug.Assert(ControlPointCount >= 4); var smv = Modules[0].GetValue(x, y, z); int ip; for (ip = 0; ip < _data.Count; ip++) { if (smv < _data[ip].Key) { break; } } var i0 = Mathf.Clamp(ip - 2, 0, _data.Count - 1); var i1 = Mathf.Clamp(ip - 1, 0, _data.Count - 1); var i2 = Mathf.Clamp(ip, 0, _data.Count - 1); var i3 = Mathf.Clamp(ip + 1, 0, _data.Count - 1); if (i1 == i2) { return _data[i1].Value; } //double ip0 = _data[i1].Value; //double ip1 = _data[i2].Value; var ip0 = _data[i1].Key; var ip1 = _data[i2].Key; var a = (smv - ip0) / (ip1 - ip0); return Utils.InterpolateCubic(_data[i0].Value, _data[i1].Value, _data[i2].Value, _data[i3].Value, a); } #endregion } }