+ class Distribution {
+
+ public:
+ Distribution(float min, float mid, float max)
+ : xmin(min), xmid(mid), xmax(max) { Update(); }
+
+ bool Valid(float x) const noexcept {
+ return x >= xmin && x <= xmax;
+ }
+ float Map(float x) const noexcept {
+ // previous algo as was used by Generator
+ //return 4.0f - ((x - xmid) * (x - xmid));
+
+ // linear mapping of [min,mid,max] to [-1,0,1]
+ x -= xmid;
+ x *= (x < 0) ? inv_neg : inv_pos;
+
+ // smoothing: x^4 - 2x^2 + 1
+ x *= x;
+ return x * x - 2.0f * x + 1.0f;
+ }
+
+ void Min(float m) noexcept { xmin = m; Update(); }
+ float Min() const noexcept { return xmin; }
+ void Mid(float m) noexcept { xmid = m; Update(); }
+ float Mid() const noexcept { return xmid; }
+ void Max(float m) noexcept { xmax = m; Update(); }
+ float Max() const noexcept { return xmax; }
+
+ private:
+ void Update() {
+ float abs_min = std::abs(xmin - xmid);
+ inv_neg = abs_min < std::numeric_limits<float>::epsilon() ? 0.0f : 1.0f / abs_min;
+ float abs_max = std::abs(xmax - xmid);
+ inv_pos = abs_max < std::numeric_limits<float>::epsilon() ? 0.0f : 1.0f / abs_max;
+ }
+
+ float xmin;
+ float xmid;
+ float xmax;
+ float inv_neg;
+ float inv_pos;
+
+ };
+
+ Distribution solidity;
+ Distribution humidity;
+ Distribution temperature;
+ Distribution richness;