From 9b0abd8f7a0d3316d327cee35beaf46d2cb7af94 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 18 May 2015 22:02:10 +1000 Subject: [PATCH] noise: parameterise fractal summation types --- noise.cpp | 14 +++-- noise.hpp | 5 +- noise/fractal.cpp | 146 +++++++++++++++++++++++++++------------------- noise/fractal.hpp | 39 +++++++------ tools/noise.cpp | 6 +- 5 files changed, 122 insertions(+), 88 deletions(-) diff --git a/noise.cpp b/noise.cpp index 2260dcf7..a752c944 100644 --- a/noise.cpp +++ b/noise.cpp @@ -24,25 +24,29 @@ //----------------------------------------------------------------------------- +template void -util::noise::fill (image::buffer &pixels, - const util::noise::fractal &gen) +util::noise::fill (image::buffer &pixels, + const util::noise::fractal &gen) { size_t h = pixels.h, s = pixels.s, w = pixels.w; - float *data = pixels.data (); + T *data = pixels.data (); for (size_t y = 0; y < h; ++y) for (size_t x = 0; x < w; ++x) - data[y * s + x] = gen (double(x), double(y)); + data[y * s + x] = gen (x, y); } +template void util::noise::fill (image::buffer&, const util::noise::fractal&); +template void util::noise::fill (image::buffer&, const util::noise::fractal&); + //----------------------------------------------------------------------------- void util::noise::image2d (uint8_t *restrict pixels, size_t width, size_t height, - const util::noise::fractal &p) { + const util::noise::fractal &p) { for (size_t y = 0; y < height; ++y) for (size_t x = 0; x < width; ++x) { double v = p.eval (x, y); diff --git a/noise.hpp b/noise.hpp index d74e2c51..f4ef02a6 100644 --- a/noise.hpp +++ b/noise.hpp @@ -27,9 +27,10 @@ namespace util { namespace noise { - void fill (image::buffer&, const util::noise::fractal&); + template + void fill (image::buffer&, const util::noise::fractal&); - void image2d (uint8_t *restrict pixels, size_t width, size_t height, const util::noise::fractal&); + void image2d (uint8_t *restrict pixels, size_t width, size_t height, const util::noise::fractal&); } } diff --git a/noise/fractal.cpp b/noise/fractal.cpp index d2862d6a..f4d5cca1 100644 --- a/noise/fractal.cpp +++ b/noise/fractal.cpp @@ -21,10 +21,16 @@ #include +using util::noise::fractal; +using util::noise::fbm; +using util::noise::musgrave; + + /////////////////////////////////////////////////////////////////////////////// -util::noise::fractal::fractal (unsigned _octaves, - double _frequency, - double _lacunarity): +template +fractal::fractal (unsigned _octaves, + T _frequency, + T _lacunarity): octaves (_octaves), frequency (_frequency), lacunarity (_lacunarity) @@ -32,54 +38,64 @@ util::noise::fractal::fractal (unsigned _octaves, //----------------------------------------------------------------------------- -util::noise::fractal::fractal (): +template +fractal::fractal (): octaves (1), - frequency (0.1), - lacunarity (0.6) + frequency (T(0.1)), + lacunarity (T(0.6)) { ; } //----------------------------------------------------------------------------- -util::noise::fractal::~fractal () +template +fractal::~fractal () { ; } //----------------------------------------------------------------------------- -double -util::noise::fractal::eval (double, double) const +template +T +fractal::eval (T, T) const { unreachable (); } +//----------------------------------------------------------------------------- +namespace util { namespace noise { + template struct fractal; + template struct fractal; +} } + + /////////////////////////////////////////////////////////////////////////////// -template -util::noise::fbm::fbm (unsigned _octaves, - double _frequency, - double _lacunarity, - seed_t _seed): - fractal (_octaves, _frequency, _lacunarity), +template +fbm::fbm (unsigned _octaves, + T _frequency, + T _lacunarity, + seed_t _seed): + fractal (_octaves, _frequency, _lacunarity), basis (_seed) { ; } //----------------------------------------------------------------------------- -template -util::noise::fbm::fbm () +template +fbm::fbm () { ; } //----------------------------------------------------------------------------- -template -double -util::noise::fbm::eval (double x, double y) const { - double total = 0.0; - double f = this->frequency; - double a = 1.0; - double a_sum = 0.0; +template +T +fbm::eval (T x, T y) const { + T total = 0; + T f = this->frequency; + T a = 1; + T a_sum = 0; for (size_t i = 0; i < this->octaves; ++i) { total += basis.eval (x * f, y * f) * a; - f *= 2.0; + f *= 2; a_sum += a; a *= this->lacunarity; @@ -90,65 +106,71 @@ util::noise::fbm::eval (double x, double y) const { //----------------------------------------------------------------------------- -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; -template struct util::noise::fbm>; +template struct util::noise::fbm>; +template struct util::noise::fbm>; +template struct util::noise::fbm>; +template struct util::noise::fbm>; +template struct util::noise::fbm>; + +template struct util::noise::fbm>; +template struct util::noise::fbm>; +template struct util::noise::fbm>; +template struct util::noise::fbm>; +template struct util::noise::fbm>; /////////////////////////////////////////////////////////////////////////////// -template -util::noise::musgrave::musgrave (unsigned _octaves, - double _frequency, - double _lacunarity, - seed_t _seed): - fractal (_octaves, _frequency, _lacunarity), +template +musgrave::musgrave (unsigned _octaves, + T _frequency, + T _lacunarity, + seed_t _seed): + fractal (_octaves, _frequency, _lacunarity), basis (_seed) { ; } //----------------------------------------------------------------------------- -template -util::noise::musgrave::musgrave () +template +musgrave::musgrave () { ; } //----------------------------------------------------------------------------- -template -double -util::noise::musgrave::eval (double x, double y) const { - double total = 0.0; - double f = this->frequency; - double a = 1.0; +template +T +musgrave::eval (T x, T y) const { + T total = 0; + T f = this->frequency; + T a = 1; - double weight = 1.0; - double offset = 1.0; - double gain = 2.0; + T weight = 1; + T offset = 1; + T gain = 2; - double signal; + T signal; signal = basis.eval (x * f, y * f); - signal = fabs (signal); + signal = std::fabs (signal); signal = offset - signal; signal *= signal; total = signal; for (size_t i = 1; i < this->octaves; ++i) { - f *= 2.0; - a *= this->lacunarity; + f *= 2; + a *= this->lacunarity; weight = signal * gain; - weight = max (0.0, min (1.0, weight)); + weight = limit (weight, 0, 1); signal = basis.eval (x * f, y * f); - signal = fabs (signal); + signal = std::fabs (signal); signal = offset - signal; signal *= signal; signal *= weight; total += signal * a; - total = min (1.0, max (0.0, total)); + total = limit (total, 0, 1); } return total; @@ -156,9 +178,15 @@ util::noise::musgrave::eval (double x, double y) const { //----------------------------------------------------------------------------- -template struct util::noise::musgrave>; -template struct util::noise::musgrave>; -template struct util::noise::musgrave>; -template struct util::noise::musgrave>; -template struct util::noise::musgrave>; +template struct util::noise::musgrave>; +template struct util::noise::musgrave>; +template struct util::noise::musgrave>; +template struct util::noise::musgrave>; +template struct util::noise::musgrave>; + +template struct util::noise::musgrave>; +template struct util::noise::musgrave>; +template struct util::noise::musgrave>; +template struct util::noise::musgrave>; +template struct util::noise::musgrave>; diff --git a/noise/fractal.hpp b/noise/fractal.hpp index ce4fbf6e..8d9a583d 100644 --- a/noise/fractal.hpp +++ b/noise/fractal.hpp @@ -22,51 +22,52 @@ namespace util { namespace noise { /// Base noise summation + template struct fractal { - fractal (unsigned octaves, - double frequency, - double lacunarity); + fractal (unsigned octaves, + T frequency, + T lacunarity); fractal (); virtual ~fractal (); unsigned octaves; - double frequency; - double lacunarity; + T frequency; + T lacunarity; - virtual double operator() (double x, double y) const { return eval (x, y); }; - virtual double eval (double x, double y) const = 0; + T operator() (T x, T y) const { return eval (x, y); }; + virtual T eval (T x, T y) const = 0; }; /// Fractal Brownian Motion summation. - template - struct fbm : public fractal { - using seed_t = typename basis::seed_t; + template + struct fbm : public fractal { + using seed_t = typename basis::seed_t; fbm (unsigned octaves, - double frequency, - double lacunarity, + T frequency, + T lacunarity, seed_t seed); fbm (); B basis; - virtual double eval (double x, double y) const; + virtual T eval (T x, T y) const; }; /// Rigid Multifractal noise summation. - template - struct musgrave : public fractal { - using seed_t = typename basis::seed_t; + template + struct musgrave : public fractal { + using seed_t = typename basis::seed_t; musgrave (unsigned octaves, - double frequency, - double lacunarity, + T frequency, + T lacunarity, seed_t seed); musgrave (); B basis; - virtual double eval (double x, double y) const; + virtual T eval (T x, T y) const; }; } } diff --git a/tools/noise.cpp b/tools/noise.cpp index a369d8e6..2eeac5eb 100644 --- a/tools/noise.cpp +++ b/tools/noise.cpp @@ -11,9 +11,9 @@ main (void) //using basis_t = util::noise::gradient; //using noise_t = util::noise::fbm; - using noise_t = util::noise::fbm>; - //using noise_t = util::noise::musgrave>; - //using noise_t = util::noise::fbm>; + using noise_t = util::noise::fbm>; + //using noise_t = util::noise::musgrave>; + //using noise_t = util::noise::fbm>; util::noise::fill (img, noise_t {});