#ifndef SIMPLEXNOISE_H #define SIMPLEXNOISE_H #include #include #include #include // #include "Array2D.h" #include "kblib/simple.h" class SimplexNoise { public: SimplexNoise(unsigned Octaves, float Gain, float Lacunarity, float Frequency = 0.002f, float Amplitude = 50.0f); // void makeSomeNoise(Array_2D& height_map, int z); std::vector> genNoise(const std::valarray& xgrid, const std::valarray& ygrid, float z); private: std::array permutation_table; // randomized tables float gradient_table[8][3]; unsigned max_octaves; // Fractional Brownian Motion variables float lacunarity; float gain; float start_frequency; float start_amplitude; float make_point(float x, float y, float z); std::valarray make_points(std::valarray x, std::valarray y, std::valarray z); }; namespace OlsenNoise { // std::vector> genNoise(std::vector xgrid, // std::vector ygrid); std::vector> genNoise(int x_start, int y_start, int width, int height); constexpr int maxIterations = 7; namespace priv { constexpr std::array, 3> blur3x3 = { {{1, 1, 1}, {1, 1, 1}, {1, 1, 1}}}; constexpr int blurEdge = 2, scaleFactor = 2; }; // namespace priv inline void olsennoise(int iterations, std::vector& pixels, int stride, int x, int y, int width, int height); inline void olsennoise(std::vector& pixels, int stride, int x, int y, int width, int height); inline constexpr int getRequiredDim(int dim) { return dim + priv::blurEdge + priv::scaleFactor; } void convolve(std::vector& pixels, int offset, int stride, int x, int y, int width, int height, const std::array, 3>& matrix = priv::blur3x3); std::vector trim(int width, int height, const std::vector& workingpixels, int workingstride); inline unsigned hashrandom(const std::vector& elements); inline unsigned FNV(const std::vector& data) { return kblib::FNV32a_s(reinterpret_cast(data.data()), data.size() * sizeof(*data.begin())); } namespace priv { void olsennoise(std::vector& pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration); void applyNoise(std::vector& pixels, int stride, int x_within_field, int y_within_field, int width, int height, int iteration); void applyScale(std::vector& pixels, int stride, int width, int height, int factor); void applyShift(std::vector& pixels, int stride, int shiftX, int shiftY, int width, int height); void clearValues(std::vector& pixels, int stride, int width, int height); void applyBlur(std::vector& pixels, int stride, int width, int height); inline constexpr int crimp(int color) { return (color >= 0xFF) ? 0xFF : (color < 0) ? 0 : color; } int convolve(std::vector& pixels, int stride, int index, const std::array, 3>& matrix); inline unsigned long long hash(unsigned long long hash) { unsigned long long h = hash; switch (hash & 3) { case 3: hash += h; hash ^= hash << 32; hash ^= h << 36; hash += hash >> 22; break; case 2: hash += h; hash ^= hash << 22; hash += hash >> 34; break; case 1: hash += h; hash ^= hash << 20; hash += hash >> 2; } hash ^= hash << 6; hash += hash >> 10; hash ^= hash << 8; hash += hash >> 34; hash ^= hash << 50; hash += hash >> 12; return hash; } }; // namespace priv inline void olsennoise(int iterations, std::vector& pixels, int stride, int x, int y, int width, int height) { priv::olsennoise(pixels, stride, x, y, width, height, iterations); // Calls the main routine. } inline void olsennoise(std::vector& pixels, int stride, int x, int y, int width, int height) { priv::olsennoise(pixels, stride, x, y, width, height, maxIterations); } unsigned hashrandom(const std::vector& elements) { unsigned long long hash{0}; for (auto i : elements) { hash ^= i; hash = priv::hash(hash); } return static_cast(hash); } }; // namespace OlsenNoise #endif