/// <summary> /// See the documentation on the base class. /// <seealso cref="Module"/> /// </summary> /// <param name="x">X coordinate</param> /// <param name="y">Y coordinate</param> /// <param name="z">Z coordinate</param> /// <returns>Returns the computed value</returns> public override double GetValue(double x, double y, double z) { // Get the output value from the source module. double sourceModuleValue = SourceModules[0].GetValue(x, y, z); // Find the first element in the control point array that has a value // larger than the output value from the source module. int indexPos; for (indexPos = 0; indexPos < ControlPoints.Count; indexPos++) { if (sourceModuleValue < ControlPoints[indexPos].x) { break; } } // Find the two nearest control points so that we can map their values // onto a quadratic curve. var index0 = NoiseMath.Clamp(indexPos - 1, 0, ControlPoints.Count - 1); var index1 = NoiseMath.Clamp(indexPos, 0, ControlPoints.Count - 1); // If some control points are missing (which occurs if the output value from // the source module is greater than the largest value or less than the // smallest value of the control point array), get the value of the nearest // control point and exit now. if (index0 == index1) { return(ControlPoints[index1].x); } // Compute the alpha value used for linear interpolation. var value0 = ControlPoints[index0].x; var value1 = ControlPoints[index1].x; var alpha = (sourceModuleValue - value0) / (value1 - value0); if (InvertTerraces) { alpha = 1.0 - alpha; NoiseMath.Swap(ref value0, ref value1); } // Squaring the alpha produces the terrace effect. alpha *= alpha; // Now perform the linear interpolation given the alpha value. return(NoiseMath.Linear(value0, value1, alpha)); }