--- deliantra/server/include/noise.h 2011/04/26 14:41:35 1.9 +++ deliantra/server/include/noise.h 2011/05/01 13:18:23 1.12 @@ -31,6 +31,85 @@ typedef blitz::TinyVector vec2d; typedef blitz::TinyVector vec3d; +vec2d +inline floor (vec2d v) +{ + return vec2d (fastfloor (v[0]), fastfloor (v[1])); +} + +vec3d +inline floor (vec3d v) +{ + return vec3d (fastfloor (v[0]), fastfloor (v[1]), fastfloor (v[2])); +} + +vec2d +inline pow (vec2d v, vec2d p) +{ + return vec2d (pow (v[0], p[0]), pow (v[1], p[1])); +} + +///////////////////////////////////////////////////////////////////////////// + +// various s-shaped curves, smooth to, first, or second derivative +// used for smooth interpolation from 0..1 + +// linear +template +inline T +sigmoid0 (T x) +{ + return x; +} + +// 3x²-2x³ +template +inline T +sigmoid1 (T x) +{ + return (3 - 2 * x) * x * x; +} + +// 6x⁵ - 15x⁴ + 10x³ +template +inline T +sigmoid2 (T x) +{ +#ifdef MORE_PARALLELITY + float x2 = x * x; + float x4 = x2 * x2; + + return (6 * x4 + 10 * x2) * x - 15 * x4; +#endif + + // simple horner + return ((6 * x - 15) * x + 10) * x * x * x; +} + +// blend between a and b +// c is the control function - if lower than ca +// then return a, if higher than cb, return b +template +inline T +blend (T a, T b, U c, U ca, U cb, U weight (U) = sigmoid1) +{ + if (c <= ca) return a; + if (c >= cb) return b; + + U w = weight ((c - ca) / (cb - ca)); + return (U(1) - w) * a + w * b; +} + +// blend between a and b +// c is the control function - if lower than -c_w +// then return a, if higher than +c_w then b. +template +inline T +blend0 (T a, T b, U c, U c_w, U weight (U) = sigmoid1) +{ + return blend (a, b, c, -c_w, c_w, weight); +} + template struct rotate_nn { @@ -68,7 +147,7 @@ ///////////////////////////////////////////////////////////////////////////// -template +template< int N, typename T> struct permutation { T pmap[N]; @@ -77,7 +156,7 @@ T operator ()(T v) func_pure { - return pmap[v & (N - 1)]; + return pmap[v & T(N - 1)]; } }; @@ -86,12 +165,14 @@ template struct noise_gen_base { - permutation<256, uint8_t> rvmap[vec_t::numElements]; + permutation<256, uint8_t> rvmap[vec_t::numElements + 1]; + + typedef typename vec_t::T_numtype value_t; void seed (seedable_rand_gen &rng); void seed (seed_t seed); - typename vec_t::T_numtype operator ()(vec_t P) func_pure; + value_t operator ()(vec_t P, uint32_t seed = 0) func_pure; }; template @@ -102,7 +183,7 @@ struct noise_gen : noise_gen_base { - static vec2d::T_numtype abs_avg() { return 0.2231; } // avg(abs(noise)) + static value_t abs_avg() { return 0.2231; } // avg(abs(noise)) }; template<> @@ -114,14 +195,13 @@ using noise_gen_base::operator (); // noise projected on a surface with normal n - vec2d::T_numtype operator() (vec3d P, vec3d N) func_pure; + vec2d::T_numtype operator() (vec3d P, vec3d N, uint32_t seed = 0) func_pure; }; -template -struct perturb_gen -{ - //TODO -}; +typedef noise_gen noise2d; +typedef noise_gen noise3d; + +///////////////////////////////////////////////////////////////////////////// template struct frac_gen @@ -131,27 +211,47 @@ typedef typename vec_t::T_numtype value_t; + int octaves; value_t h, lac, ex[MAX_OCTAVES]; value_t fbm_mul[MAX_OCTAVES]; rotate_xy rot[MAX_OCTAVES]; - frac_gen (value_t hurst_expo = .5, value_t lacunarity = 2, uint32_t seed = 0); + frac_gen (int octaves = 3, value_t lacunarity = 2, value_t hurst_expo = .5, uint32_t seed = 0); - value_t noise (vec_t P) func_pure + value_t noise (vec_t P, uint32_t seed = 0) func_pure { - return operator() (P); + return operator() (P, seed); } - value_t fBm (vec_t P, int octaves) func_pure; - value_t turbulence (vec_t P, int octaves) func_pure; - value_t multifractal (vec_t P, int octaves, value_t offset = 1) func_pure; - value_t heterofractal (vec_t P, int octaves, value_t offset = 1) func_pure; - value_t hybridfractal (vec_t P, int octaves, value_t offset = 1, value_t gain = 1) func_pure; - value_t ridgedmultifractal (vec_t P, int octaves, value_t offset = 1, value_t gain = 8) func_pure; - value_t billowfractal (vec_t P, int octaves, value_t offset = 1, value_t gain = 2) func_pure; - value_t terrain (vec_t P, int octaves) func_pure; - value_t terrain2 (vec_t P, int octaves) func_pure; + value_t fBm (vec_t P) func_pure; + value_t turbulence (vec_t P) func_pure; + value_t multifractal (vec_t P, value_t offset = 1) func_pure; + value_t heterofractal (vec_t P, value_t offset = 1) func_pure; + value_t hybridfractal (vec_t P, value_t offset = 1, value_t gain = 1) func_pure; + value_t ridgedmultifractal (vec_t P, value_t offset = 1, value_t gain = 8) func_pure; + value_t billowfractal (vec_t P, value_t offset = 1, value_t gain = 2) func_pure; + value_t terrain (vec_t P) func_pure; + value_t terrain2 (vec_t P) func_pure; }; +typedef frac_gen frac2d; +typedef frac_gen frac3d; + +///////////////////////////////////////////////////////////////////////////// + +template +T +inline border_blend (T a, T b, vec2d P, U N, U W) +{ + U border = W; // within n places of the border + + min_it (border, P [0]); + min_it (border, N - P [0]); + min_it (border, P [1]); + min_it (border, N - P [1]); + + return blend (a, b,border, U(0), W); +} + #endif