X-Git-Url: https://git.localhorst.tv/?a=blobdiff_plain;ds=sidebyside;f=src%2Fworld%2FBlockType.hpp;h=f1b887d3eabc56e998fd64917c8a661df9df52b9;hb=fda38181732e58537331c919dd699eaa830ead50;hp=3ca170a200ba65367ff604bfbada3645456714b1;hpb=1a8d4d31ef0a094ef6488127c5f873040151cb57;p=blank.git diff --git a/src/world/BlockType.hpp b/src/world/BlockType.hpp index 3ca170a..f1b887d 100644 --- a/src/world/BlockType.hpp +++ b/src/world/BlockType.hpp @@ -9,6 +9,7 @@ #include "../model/Shape.hpp" #include +#include #include @@ -58,20 +59,58 @@ struct BlockType { // generation properties /// whether to use this block in generation at all bool generate; + // min/mid/max points for the respective properties // should all be in the (-1,1) range - float min_solidity; - float mid_solidity; - float max_solidity; - float min_humidity; - float mid_humidity; - float max_humidity; - float min_temperature; - float mid_temperature; - float max_temperature; - float min_richness; - float mid_richness; - float max_richness; + 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::epsilon() ? 0.0f : 1.0f / abs_min; + float abs_max = std::abs(xmax - xmid); + inv_pos = abs_max < std::numeric_limits::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; /// commonness factor, random chance is multiplied by this float commonness;