From 59706820354191edc7f5941f2f9a4bd711fdf36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Leclercq?= Date: Sat, 18 Jun 2016 12:36:20 +0200 Subject: [PATCH] Noise: First pass of refactoring Former-commit-id: 77de49ee01fea466cb97b22771e4c625389fd95c [formerly edce9427bc009c8ea6a6df35d9ce134a83ab985c] Former-commit-id: 76227519c8be75a45f6f65250a0870c2eb866953 --- include/Nazara/Math/Algorithm.hpp | 5 + include/Nazara/Noise/FBM.hpp | 4 +- include/Nazara/Noise/HybridMultiFractal.hpp | 4 +- include/Nazara/Noise/MixerBase.hpp | 4 + include/Nazara/Noise/NoiseBase.hpp | 17 +- include/Nazara/Noise/Perlin.hpp | 20 +- include/Nazara/Noise/Simplex.hpp | 27 +- include/Nazara/Noise/Worley.hpp | 23 +- src/Nazara/Noise/FBM.cpp | 45 ++- src/Nazara/Noise/HybridMultiFractal.cpp | 64 +++- src/Nazara/Noise/NoiseBase.cpp | 62 ++-- src/Nazara/Noise/Perlin.cpp | 239 +++++------- src/Nazara/Noise/Simplex.cpp | 388 ++++++++------------ src/Nazara/Noise/Worley.cpp | 118 +++--- 14 files changed, 485 insertions(+), 535 deletions(-) diff --git a/include/Nazara/Math/Algorithm.hpp b/include/Nazara/Math/Algorithm.hpp index 74cc45593..45281bb50 100644 --- a/include/Nazara/Math/Algorithm.hpp +++ b/include/Nazara/Math/Algorithm.hpp @@ -1,3 +1,4 @@ + // Copyright (C) 2015 Jérôme Leclercq // This file is part of the "Nazara Engine - Mathematics module" // For conditions of distribution and use, see copyright notice in Config.hpp @@ -28,6 +29,10 @@ #define M_SQRT3 1.7320508075688772935274463 #endif +#ifndef M_SQRT5 +#define M_SQRT5 2.23606797749979 +#endif + namespace Nz { template /*constexpr*/ T Approach(T value, T objective, T increment); diff --git a/include/Nazara/Noise/FBM.hpp b/include/Nazara/Noise/FBM.hpp index ded4aa069..584fb3a10 100644 --- a/include/Nazara/Noise/FBM.hpp +++ b/include/Nazara/Noise/FBM.hpp @@ -18,7 +18,9 @@ namespace Nz FBM(const FBM&) = delete; ~FBM() = default; - float Get(std::initializer_list coordinates, float scale) const; + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; FBM& operator=(const FBM&) = delete; diff --git a/include/Nazara/Noise/HybridMultiFractal.hpp b/include/Nazara/Noise/HybridMultiFractal.hpp index a211a4767..c73dafc73 100644 --- a/include/Nazara/Noise/HybridMultiFractal.hpp +++ b/include/Nazara/Noise/HybridMultiFractal.hpp @@ -17,7 +17,9 @@ namespace Nz HybridMultiFractal(const HybridMultiFractal&) = delete; ~HybridMultiFractal() = default; - float Get(std::initializer_list coordinates, float scale) const; + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; HybridMultiFractal& operator=(const HybridMultiFractal&) = delete; diff --git a/include/Nazara/Noise/MixerBase.hpp b/include/Nazara/Noise/MixerBase.hpp index 3c7a131b0..8b7a99d56 100644 --- a/include/Nazara/Noise/MixerBase.hpp +++ b/include/Nazara/Noise/MixerBase.hpp @@ -17,6 +17,10 @@ namespace Nz MixerBase(); ~MixerBase() = default; + virtual float Get(float x, float y, float scale) const = 0; + virtual float Get(float x, float y, float z, float scale) const = 0; + virtual float Get(float x, float y, float z, float w, float scale) const = 0; + float GetHurstParameter() const; float GetLacunarity() const; float GetOctaveNumber() const; diff --git a/include/Nazara/Noise/NoiseBase.hpp b/include/Nazara/Noise/NoiseBase.hpp index 6a5c5c37f..f7f9eba09 100644 --- a/include/Nazara/Noise/NoiseBase.hpp +++ b/include/Nazara/Noise/NoiseBase.hpp @@ -6,7 +6,11 @@ #define NAZARA_NOISEBASE_HPP #include +#include +#include +#include #include +#include #include namespace Nz @@ -17,21 +21,26 @@ namespace Nz NoiseBase(unsigned int seed = 0); ~NoiseBase() = default; - virtual float Get(std::initializer_list coordinates, float scale) const = 0; + virtual float Get(float x, float y, float scale) const = 0; + virtual float Get(float x, float y, float z, float scale) const = 0; + virtual float Get(float x, float y, float z, float w, float scale) const = 0; float GetScale(); void SetScale(float scale); void SetSeed(unsigned int seed); void Shuffle(); - void Shuffle(unsigned int amount); protected: - unsigned int perm[512]; + std::array m_permutations; float m_scale; + static std::array s_gradients2; + static std::array s_gradients3; + static std::array s_gradients4; + private: - std::default_random_engine generator; + std::default_random_engine m_randomEngine; }; } diff --git a/include/Nazara/Noise/Perlin.hpp b/include/Nazara/Noise/Perlin.hpp index 058a3ada5..781d03148 100644 --- a/include/Nazara/Noise/Perlin.hpp +++ b/include/Nazara/Noise/Perlin.hpp @@ -15,21 +15,13 @@ namespace Nz class NAZARA_NOISE_API Perlin : public NoiseBase { public: - Perlin(); - Perlin(unsigned int seed); - ~Perlin() = default; + Perlin() = default; + Perlin(unsigned int seed); + ~Perlin() = default; - float Get(std::initializer_list coordinates, float scale) const; - - protected: - float _2D(std::initializer_list coordinates, float scale) const; - float _3D(std::initializer_list coordinates, float scale) const; - float _4D(std::initializer_list coordinates, float scale) const; - - private: - const float gradient2[8][2]; - const float gradient3[16][3]; - const float gradient4[32][4]; + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; }; } diff --git a/include/Nazara/Noise/Simplex.hpp b/include/Nazara/Noise/Simplex.hpp index f131387b6..ae018f7bf 100644 --- a/include/Nazara/Noise/Simplex.hpp +++ b/include/Nazara/Noise/Simplex.hpp @@ -15,28 +15,13 @@ namespace Nz class NAZARA_NOISE_API Simplex : public NoiseBase { public: - Simplex(); - Simplex(unsigned int seed); - ~Simplex() = default; + Simplex() = default; + Simplex(unsigned int seed); + ~Simplex() = default; - float Get(std::initializer_list coordinates, float scale) const; - - protected: - float _2D(std::initializer_list coordinates, float scale) const; - float _3D(std::initializer_list coordinates, float scale) const; - float _4D(std::initializer_list coordinates, float scale) const; - - private: - const float gradient2[8][2]; - const float gradient3[16][3]; - const float gradient4[32][4]; - const float UnskewCoeff2D; - const float SkewCoeff2D; - const float UnskewCoeff3D; - const float SkewCoeff3D; - const float UnskewCoeff4D; - const float SkewCoeff4D; - const int lookupTable4D[64][4]; + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; }; } diff --git a/include/Nazara/Noise/Worley.hpp b/include/Nazara/Noise/Worley.hpp index 249da999f..6b9f21f73 100644 --- a/include/Nazara/Noise/Worley.hpp +++ b/include/Nazara/Noise/Worley.hpp @@ -18,23 +18,20 @@ namespace Nz class NAZARA_NOISE_API Worley : public NoiseBase { public: - Worley(); - Worley(unsigned int seed); - ~Worley() = default; + Worley(); + Worley(unsigned int seed); + ~Worley() = default; - void Set(WorleyFunction func); + float Get(float x, float y, float scale) const override; + float Get(float x, float y, float z, float scale) const override; + float Get(float x, float y, float z, float w, float scale) const override; - float Get(std::initializer_list coordinates, float scale) const; - - protected: - float _2D(std::initializer_list coordinates, float scale) const; - float _3D(std::initializer_list coordinates, float scale) const; - float _4D(std::initializer_list coordinates, float scale) const; - void _SquareTest(int xi, int yi, float x, float y, std::map & featurePoints) const; + void Set(WorleyFunction func); private: - const float scales[4]; - WorleyFunction function; + void SquareTest(int xi, int yi, float x, float y, std::map & featurePoints) const; + + WorleyFunction m_function; }; } diff --git a/src/Nazara/Noise/FBM.cpp b/src/Nazara/Noise/FBM.cpp index f61bf8f44..96126ec60 100644 --- a/src/Nazara/Noise/FBM.cpp +++ b/src/Nazara/Noise/FBM.cpp @@ -11,20 +11,51 @@ namespace Nz { } - float FBM::Get(std::initializer_list coordinates, float scale) const + ///TODO: Handle with variadic templates + float FBM::Get(float x, float y, float scale) const { - float value = 0.0; - - for(int i(0); i < m_octaves; ++i) + float value = 0.f; + for(int i = 0; i < m_octaves; ++i) { - value += m_source.Get(coordinates,scale) * m_exponent_array.at(i); + value += m_source.Get(x, y, scale) * m_exponent_array.at(i); scale *= m_lacunarity; } float remainder = m_octaves - static_cast(m_octaves); - if(std::fabs(remainder) > 0.01f) - value += remainder * m_source.Get(coordinates,scale) * m_exponent_array.at(static_cast(m_octaves-1)); + value += remainder * m_source.Get(x, y, scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum; + } + + float FBM::Get(float x, float y, float z, float scale) const + { + float value = 0.f; + for(int i = 0; i < m_octaves; ++i) + { + value += m_source.Get(x, y, z, scale) * m_exponent_array.at(i); + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + if(std::fabs(remainder) > 0.01f) + value += remainder * m_source.Get(x, y, z, scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum; + } + + float FBM::Get(float x, float y, float z, float w, float scale) const + { + float value = 0.f; + for(int i = 0; i < m_octaves; ++i) + { + value += m_source.Get(x, y, z, w, scale) * m_exponent_array.at(i); + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + if(std::fabs(remainder) > 0.01f) + value += remainder * m_source.Get(x, y, z, w, scale) * m_exponent_array.at(static_cast(m_octaves-1)); return value / m_sum; } diff --git a/src/Nazara/Noise/HybridMultiFractal.cpp b/src/Nazara/Noise/HybridMultiFractal.cpp index 3f20809d3..4278d23b2 100644 --- a/src/Nazara/Noise/HybridMultiFractal.cpp +++ b/src/Nazara/Noise/HybridMultiFractal.cpp @@ -12,10 +12,10 @@ namespace Nz { } - float HybridMultiFractal::Get(std::initializer_list coordinates, float scale) const + float HybridMultiFractal::Get(float x, float y, float scale) const { float offset = 1.0f; - float value = (m_source.Get(coordinates,scale) + offset) * m_exponent_array.at(0); + float value = (m_source.Get(x, y, scale) + offset) * m_exponent_array.at(0); float weight = value; float signal = 0.f; @@ -26,7 +26,7 @@ namespace Nz if (weight > 1.f) weight = 1.f; - signal = (m_source.Get(coordinates,scale) + offset) * m_exponent_array.at(i); + signal = (m_source.Get(x, y, scale) + offset) * m_exponent_array.at(i); value += weight * signal; weight *= signal; scale *= m_lacunarity; @@ -35,7 +35,63 @@ namespace Nz float remainder = m_octaves - static_cast(m_octaves); if (remainder > 0.f) - value += remainder * m_source.Get(coordinates,scale) * m_exponent_array.at(static_cast(m_octaves-1)); + value += remainder * m_source.Get(x, y, scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum - offset; + } + + float HybridMultiFractal::Get(float x, float y, float z, float scale) const + { + float offset = 1.0f; + float value = (m_source.Get(x, y, z, scale) + offset) * m_exponent_array.at(0); + float weight = value; + float signal = 0.f; + + scale *= m_lacunarity; + + for(int i(1) ; i < m_octaves; ++i) + { + if (weight > 1.f) + weight = 1.f; + + signal = (m_source.Get(x, y, z, scale) + offset) * m_exponent_array.at(i); + value += weight * signal; + weight *= signal; + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + + if (remainder > 0.f) + value += remainder * m_source.Get(x, y, z, scale) * m_exponent_array.at(static_cast(m_octaves-1)); + + return value / m_sum - offset; + } + + float HybridMultiFractal::Get(float x, float y, float z, float w, float scale) const + { + float offset = 1.0f; + float value = (m_source.Get(x, y, z, w, scale) + offset) * m_exponent_array.at(0); + float weight = value; + float signal = 0.f; + + scale *= m_lacunarity; + + for(int i(1) ; i < m_octaves; ++i) + { + if (weight > 1.f) + weight = 1.f; + + signal = (m_source.Get(x, y, z, w, scale) + offset) * m_exponent_array.at(i); + value += weight * signal; + weight *= signal; + scale *= m_lacunarity; + } + + float remainder = m_octaves - static_cast(m_octaves); + + if (remainder > 0.f) + value += remainder * m_source.Get(x, y, z, w, scale) * m_exponent_array.at(static_cast(m_octaves-1)); return value / m_sum - offset; } diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp index 0cbee9eec..fa5a2c92f 100644 --- a/src/Nazara/Noise/NoiseBase.cpp +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -7,13 +7,13 @@ namespace Nz { - NoiseBase::NoiseBase(unsigned int seed) + NoiseBase::NoiseBase(unsigned int seed) : + m_scale(0.05f) { SetSeed(seed); - m_scale = 0.05f; - for(unsigned int i(0) ; i < 512; ++i) - perm[i] = i & 255; + // Fill permutations with initial values + std::iota(m_permutations.begin(), m_permutations.begin() + 256, 0); } float NoiseBase::GetScale() @@ -28,32 +28,46 @@ namespace Nz void NoiseBase::SetSeed(unsigned int seed) { - generator.seed(seed); + m_randomEngine.seed(seed); } void NoiseBase::Shuffle() { - int xchanger; - unsigned int ncase; + std::shuffle(m_permutations.begin(), m_permutations.begin() + 256, m_randomEngine); - for(unsigned int i(0) ; i < 256 ; i++) - perm[i] = i; - - for (unsigned int i(0); i < 256 ; ++i) - { - ncase = generator() & 255; - xchanger = perm[i]; - perm[i] = perm[ncase]; - perm[ncase] = xchanger; - } - - for(unsigned int i(256) ; i < 512; ++i) - perm[i] = perm[i & 255]; + for(std::size_t i = 1; i < (m_permutations.size() / 256); ++i) + std::copy(m_permutations.begin(), m_permutations.begin() + 256, m_permutations.begin() + 256 * i); } - void NoiseBase::Shuffle(unsigned int amount) + std::array NoiseBase::s_gradients2 = { - for(unsigned int j(0) ; j < amount ; ++j) - Shuffle(); - } + { + {1.f, 1.f}, {-1.f, 1.f}, {1.f, -1.f}, {-1.f, -1.f}, + {1.f, 0.f}, {-1.f, 0.f}, {0.f, 1.f}, { 0.f, -1.f} + } + }; + + std::array NoiseBase::s_gradients3 = + { + { + {1.f,1.f,0.f}, {-1.f, 1.f, 0.f}, {1.f, -1.f, 0.f}, {-1.f, -1.f, 0.f}, + {1.f,0.f,1.f}, {-1.f, 0.f, 1.f}, {1.f, 0.f, -1.f}, {-1.f, 0.f, -1.f}, + {0.f,1.f,1.f}, { 0.f, -1.f, 1.f}, {0.f, 1.f, -1.f}, {0.f, -1.f, -1.f}, + {1.f,1.f,0.f}, {-1.f, 1.f, 0.f}, {0.f, -1.f, 1.f}, {0.f, -1.f, -1.f} + } + }; + + std::array NoiseBase::s_gradients4 = + { + { + {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, + {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, + {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, + {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, + {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, + {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, + {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, + {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} + } + }; } diff --git a/src/Nazara/Noise/Perlin.cpp b/src/Nazara/Noise/Perlin.cpp index f184702de..e6440eb3d 100644 --- a/src/Nazara/Noise/Perlin.cpp +++ b/src/Nazara/Noise/Perlin.cpp @@ -10,68 +10,27 @@ namespace Nz { - Perlin::Perlin() : - gradient2{ - {1.f,1.f},{-1.f,1.f},{1.f,-1.f},{-1.f,-1.f}, - {1.f,0.f},{-1.f,0.f},{0.f,1.f},{0.f,-1.f} - }, - gradient3{ - {1,1,0},{-1,1,0},{1,-1,0},{-1,-1,0}, - {1,0,1},{-1,0,1},{1,0,-1},{-1,0,-1}, - {0,1,1},{0,-1,1},{0,1,-1},{0,-1,-1}, - {1,1,0},{-1,1,0},{0,-1,1},{0,-1,-1} - }, - gradient4{ - {0,1,1,1}, {0,1,1,-1}, {0,1,-1,1}, {0,1,-1,-1}, - {0,-1,1,1},{0,-1,1,-1},{0,-1,-1,1},{0,-1,-1,-1}, - {1,0,1,1}, {1,0,1,-1}, {1,0,-1,1}, {1,0,-1,-1}, - {-1,0,1,1},{-1,0,1,-1},{-1,0,-1,1},{-1,0,-1,-1}, - {1,1,0,1}, {1,1,0,-1}, {1,-1,0,1}, {1,-1,0,-1}, - {-1,1,0,1},{-1,1,0,-1},{-1,-1,0,1},{-1,-1,0,-1}, - {1,1,1,0}, {1,1,-1,0}, {1,-1,1,0}, {1,-1,-1,0}, - {-1,1,1,0},{-1,1,-1,0},{-1,-1,1,0},{-1,-1,-1,0} - } - { - - } - - Perlin::Perlin(unsigned int seed) : Perlin() + Perlin::Perlin(unsigned int seed) : + Perlin() { SetSeed(seed); Shuffle(); } - float Perlin::Get(std::initializer_list coordinates, float scale) const + float Perlin::Get(float x, float y, float scale) const { - switch(coordinates.size()) - { - case 2: - return this->_2D(coordinates,scale); - case 3: - return this->_3D(coordinates,scale); - case 4: - return this->_4D(coordinates,scale); - default: - throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4"); - } - } + float xc, yc; + int x0, y0; + int gi0,gi1,gi2,gi3; + int ii, jj; - float Perlin::_2D(std::initializer_list coordinates, float scale) const - { - thread_local float xc, yc; - thread_local int x0, y0; - thread_local int gi0,gi1,gi2,gi3; - thread_local int ii, jj; + float s,t,u,v; + float Cx,Cy; + float Li1, Li2; + float tempx,tempy; - thread_local float s,t,u,v; - thread_local float Cx,Cy; - thread_local float Li1, Li2; - thread_local float tempx,tempy; - - std::initializer_list::const_iterator it = coordinates.begin(); - - xc = *(it ) * scale; - yc = *(++it) * scale; + xc = x * scale; + yc = y * scale; x0 = fastfloor(xc); y0 = fastfloor(yc); @@ -79,10 +38,10 @@ namespace Nz ii = x0 & 255; jj = y0 & 255; - gi0 = perm[ii + perm[jj]] & 7; - gi1 = perm[ii + 1 + perm[jj]] & 7; - gi2 = perm[ii + perm[jj + 1]] & 7; - gi3 = perm[ii + 1 + perm[jj + 1]] & 7; + gi0 = m_permutations[ii + m_permutations[jj]] & 7; + gi1 = m_permutations[ii + 1 + m_permutations[jj]] & 7; + gi2 = m_permutations[ii + m_permutations[jj + 1]] & 7; + gi3 = m_permutations[ii + 1 + m_permutations[jj + 1]] & 7; tempx = xc - x0; tempy = yc - y0; @@ -90,16 +49,16 @@ namespace Nz Cx = tempx * tempx * tempx * (tempx * (tempx * 6 - 15) + 10); Cy = tempy * tempy * tempy * (tempy * (tempy * 6 - 15) + 10); - s = gradient2[gi0][0]*tempx + gradient2[gi0][1]*tempy; + s = s_gradients2[gi0][0]*tempx + s_gradients2[gi0][1]*tempy; tempx = xc - (x0 + 1); - t = gradient2[gi1][0]*tempx + gradient2[gi1][1]*tempy; + t = s_gradients2[gi1][0]*tempx + s_gradients2[gi1][1]*tempy; tempy = yc - (y0 + 1); - v = gradient2[gi3][0]*tempx + gradient2[gi3][1]*tempy; + v = s_gradients2[gi3][0]*tempx + s_gradients2[gi3][1]*tempy; tempx = xc - x0; - u = gradient2[gi2][0]*tempx + gradient2[gi2][1]*tempy; + u = s_gradients2[gi2][0]*tempx + s_gradients2[gi2][1]*tempy; Li1 = s + Cx*(t-s); Li2 = u + Cx*(v-u); @@ -107,26 +66,24 @@ namespace Nz return Li1 + Cy*(Li2-Li1); } - float Perlin::_3D(std::initializer_list coordinates, float scale) const + float Perlin::Get(float x, float y, float z, float scale) const { - thread_local float xc, yc, zc; - thread_local int x0, y0, z0; - thread_local int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; - thread_local int ii, jj, kk; + float xc, yc, zc; + int x0, y0, z0; + int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7; + int ii, jj, kk; - thread_local float Li1,Li2,Li3,Li4,Li5,Li6; - thread_local float s[2],t[2],u[2],v[2]; - thread_local float Cx,Cy,Cz; - thread_local float nx,ny,nz; + float Li1,Li2,Li3,Li4,Li5,Li6; + float s[2],t[2],u[2],v[2]; + float Cx,Cy,Cz; + float nx,ny,nz; - thread_local float tmp; - thread_local float tempx,tempy,tempz; + float tmp; + float tempx,tempy,tempz; - std::initializer_list::const_iterator it = coordinates.begin(); - - xc = *(it ) * scale; - yc = *(++it) * scale; - zc = *(++it) * scale; + xc = x * scale; + yc = y * scale; + zc = z * scale; x0 = fastfloor(xc); y0 = fastfloor(yc); @@ -136,15 +93,15 @@ namespace Nz jj = y0 & 255; kk = z0 & 255; - gi0 = perm[ii + perm[jj + perm[kk]]] & 15; - gi1 = perm[ii + 1 + perm[jj + perm[kk]]] & 15; - gi2 = perm[ii + perm[jj + 1 + perm[kk]]] & 15; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] & 15; + gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk]]] & 15; + gi1 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk]]] & 15; + gi2 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk]]] & 15; + gi3 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk]]] & 15; - gi4 = perm[ii + perm[jj + perm[kk + 1]]] & 15; - gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] & 15; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] & 15; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] & 15; + gi4 = m_permutations[ii + m_permutations[jj + m_permutations[kk + 1]]] & 15; + gi5 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + 1]]] & 15; + gi6 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + 1]]] & 15; + gi7 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1]]] & 15; tempx = xc - x0; tempy = yc - y0; @@ -154,29 +111,29 @@ namespace Nz Cy = tempy * tempy * tempy * (tempy * (tempy * 6 - 15) + 10); Cz = tempz * tempz * tempz * (tempz * (tempz * 6 - 15) + 10); - s[0] = gradient3[gi0][0]*tempx + gradient3[gi0][1]*tempy + gradient3[gi0][2]*tempz; + s[0] = s_gradients3[gi0][0]*tempx + s_gradients3[gi0][1]*tempy + s_gradients3[gi0][2]*tempz; tempx = xc - (x0 + 1); - t[0] = gradient3[gi1][0]*tempx + gradient3[gi1][1]*tempy + gradient3[gi1][2]*tempz; + t[0] = s_gradients3[gi1][0]*tempx + s_gradients3[gi1][1]*tempy + s_gradients3[gi1][2]*tempz; tempy = yc - (y0 + 1); - v[0] = gradient3[gi3][0]*tempx + gradient3[gi3][1]*tempy + gradient3[gi3][2]*tempz; + v[0] = s_gradients3[gi3][0]*tempx + s_gradients3[gi3][1]*tempy + s_gradients3[gi3][2]*tempz; tempx = xc - x0; - u[0] = gradient3[gi2][0]*tempx + gradient3[gi2][1]*tempy + gradient3[gi2][2]*tempz; + u[0] = s_gradients3[gi2][0]*tempx + s_gradients3[gi2][1]*tempy + s_gradients3[gi2][2]*tempz; tempy = yc - y0; tempz = zc - (z0 + 1); - s[1] = gradient3[gi4][0]*tempx + gradient3[gi4][1]*tempy + gradient3[gi4][2]*tempz; + s[1] = s_gradients3[gi4][0]*tempx + s_gradients3[gi4][1]*tempy + s_gradients3[gi4][2]*tempz; tempx = xc - (x0 + 1); - t[1] = gradient3[gi5][0]*tempx + gradient3[gi5][1]*tempy + gradient3[gi5][2]*tempz; + t[1] = s_gradients3[gi5][0]*tempx + s_gradients3[gi5][1]*tempy + s_gradients3[gi5][2]*tempz; tempy = yc - (y0 + 1); - v[1] = gradient3[gi7][0]*tempx + gradient3[gi7][1]*tempy + gradient3[gi7][2]*tempz; + v[1] = s_gradients3[gi7][0]*tempx + s_gradients3[gi7][1]*tempy + s_gradients3[gi7][2]*tempz; tempx = xc - x0; - u[1] = gradient3[gi6][0]*tempx + gradient3[gi6][1]*tempy + gradient3[gi6][2]*tempz; + u[1] = s_gradients3[gi6][0]*tempx + s_gradients3[gi6][1]*tempy + s_gradients3[gi6][2]*tempz; Li1 = s[0] + Cx*(t[0]-s[0]); Li2 = u[0] + Cx*(v[0]-u[0]); @@ -189,26 +146,24 @@ namespace Nz return Li5 + Cz * (Li6-Li5); } - float Perlin::_4D(std::initializer_list coordinates, float scale) const + float Perlin::Get(float x, float y, float z, float w, float scale) const { - thread_local float xc,yc,zc,wc; - thread_local int x0,y0,z0,w0; - thread_local int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; - thread_local int ii,jj,kk,ll; + float xc,yc,zc,wc; + int x0,y0,z0,w0; + int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; + int ii,jj,kk,ll; - thread_local float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; - thread_local float s[4],t[4],u[4],v[4]; - thread_local float Cx,Cy,Cz,Cw; + float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14; + float s[4],t[4],u[4],v[4]; + float Cx,Cy,Cz,Cw; - thread_local float tmp; - thread_local float tempx,tempy,tempz,tempw; + float tmp; + float tempx,tempy,tempz,tempw; - std::initializer_list::const_iterator it = coordinates.begin(); - - xc = *(it ) * scale; - yc = *(++it) * scale; - zc = *(++it) * scale; - wc = *(++it) * scale; + xc = x * scale; + yc = y * scale; + zc = z * scale; + wc = w * scale; x0 = fastfloor(xc); y0 = fastfloor(yc); @@ -220,25 +175,25 @@ namespace Nz kk = z0 & 255; ll = w0 & 255; - gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31; - gi1 = perm[ii + 1 + perm[jj + perm[kk + perm[ll]]]] & 31; - gi2 = perm[ii + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll]]]] & 31; + gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk + m_permutations[ll]]]] & 31; + gi1 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + m_permutations[ll]]]] & 31; + gi2 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll]]]] & 31; + gi3 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll]]]] & 31; - gi4 = perm[ii + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi5 = perm[ii + 1 + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31; + gi4 = m_permutations[ii + m_permutations[jj + + m_permutations[kk + 1 + m_permutations[ll]]]] & 31; + gi5 = m_permutations[ii + 1 + m_permutations[jj + + m_permutations[kk + 1 + m_permutations[ll]]]] & 31; + gi6 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll]]]] & 31; + gi7 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll]]]] & 31; - gi8 = perm[ii + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi9 = perm[ii + 1 + perm[jj + perm[kk + perm[ll + 1]]]] & 31; - gi10 = perm[ii + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; - gi11 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31; + gi8 = m_permutations[ii + m_permutations[jj + m_permutations[kk + m_permutations[ll + 1]]]] & 31; + gi9 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + m_permutations[ll + 1]]]] & 31; + gi10 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll + 1]]]] & 31; + gi11 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll + 1]]]] & 31; - gi12 = perm[ii + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi13 = perm[ii + 1 + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; - gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31; + gi12 = m_permutations[ii + m_permutations[jj + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31; + gi13 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31; + gi14 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31; + gi15 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31; tempx = xc - x0; tempy = yc - y0; @@ -250,58 +205,58 @@ namespace Nz Cz = tempz * tempz * tempz * (tempz * (tempz * 6 - 15) + 10); Cw = tempw * tempw * tempw * (tempw * (tempw * 6 - 15) + 10); - s[0] = gradient4[gi0][0]*tempx + gradient4[gi0][1]*tempy + gradient4[gi0][2]*tempz + gradient4[gi0][3]*tempw; + s[0] = s_gradients4[gi0][0]*tempx + s_gradients4[gi0][1]*tempy + s_gradients4[gi0][2]*tempz + s_gradients4[gi0][3]*tempw; tempx = xc - (x0+1); - t[0] = gradient4[gi1][0]*tempx + gradient4[gi1][1]*tempy + gradient4[gi1][2]*tempz + gradient4[gi1][3]*tempw; + t[0] = s_gradients4[gi1][0]*tempx + s_gradients4[gi1][1]*tempy + s_gradients4[gi1][2]*tempz + s_gradients4[gi1][3]*tempw; tempy = yc - (y0+1); - v[0] = gradient4[gi3][0]*tempx + gradient4[gi3][1]*tempy + gradient4[gi3][2]*tempz + gradient4[gi3][3]*tempw; + v[0] = s_gradients4[gi3][0]*tempx + s_gradients4[gi3][1]*tempy + s_gradients4[gi3][2]*tempz + s_gradients4[gi3][3]*tempw; tempx = xc - x0; - u[0] = gradient4[gi2][0]*tempx + gradient4[gi2][1]*tempy + gradient4[gi2][2]*tempz + gradient4[gi2][3]*tempw; + u[0] = s_gradients4[gi2][0]*tempx + s_gradients4[gi2][1]*tempy + s_gradients4[gi2][2]*tempz + s_gradients4[gi2][3]*tempw; tempy = yc - y0; tempz = zc - (z0+1); - s[1] = gradient4[gi4][0]*tempx + gradient4[gi4][1]*tempy + gradient4[gi4][2]*tempz + gradient4[gi4][3]*tempw; + s[1] = s_gradients4[gi4][0]*tempx + s_gradients4[gi4][1]*tempy + s_gradients4[gi4][2]*tempz + s_gradients4[gi4][3]*tempw; tempx = xc - (x0+1); - t[1] = gradient4[gi5][0]*tempx + gradient4[gi5][1]*tempy + gradient4[gi5][2]*tempz + gradient4[gi5][3]*tempw; + t[1] = s_gradients4[gi5][0]*tempx + s_gradients4[gi5][1]*tempy + s_gradients4[gi5][2]*tempz + s_gradients4[gi5][3]*tempw; tempy = yc - (y0+1); - v[1] = gradient4[gi7][0]*tempx + gradient4[gi7][1]*tempy + gradient4[gi7][2]*tempz + gradient4[gi7][3]*tempw; + v[1] = s_gradients4[gi7][0]*tempx + s_gradients4[gi7][1]*tempy + s_gradients4[gi7][2]*tempz + s_gradients4[gi7][3]*tempw; tempx = xc - x0; - u[1] = gradient4[gi6][0]*tempx + gradient4[gi6][1]*tempy + gradient4[gi6][2]*tempz + gradient4[gi6][3]*tempw; + u[1] = s_gradients4[gi6][0]*tempx + s_gradients4[gi6][1]*tempy + s_gradients4[gi6][2]*tempz + s_gradients4[gi6][3]*tempw; tempy = yc - y0; tempz = zc - z0; tempw = wc - (w0+1); - s[2] = gradient4[gi8][0]*tempx + gradient4[gi8][1]*tempy + gradient4[gi8][2]*tempz + gradient4[gi8][3]*tempw; + s[2] = s_gradients4[gi8][0]*tempx + s_gradients4[gi8][1]*tempy + s_gradients4[gi8][2]*tempz + s_gradients4[gi8][3]*tempw; tempx = xc - (x0+1); - t[2] = gradient4[gi9][0]*tempx + gradient4[gi9][1]*tempy + gradient4[gi9][2]*tempz + gradient4[gi9][3]*tempw; + t[2] = s_gradients4[gi9][0]*tempx + s_gradients4[gi9][1]*tempy + s_gradients4[gi9][2]*tempz + s_gradients4[gi9][3]*tempw; tempy = yc - (y0+1); - v[2] = gradient4[gi11][0]*tempx + gradient4[gi11][1]*tempy + gradient4[gi11][2]*tempz + gradient4[gi11][3]*tempw; + v[2] = s_gradients4[gi11][0]*tempx + s_gradients4[gi11][1]*tempy + s_gradients4[gi11][2]*tempz + s_gradients4[gi11][3]*tempw; tempx = xc - x0; - u[2] = gradient4[gi10][0]*tempx + gradient4[gi10][1]*tempy + gradient4[gi10][2]*tempz + gradient4[gi10][3]*tempw; + u[2] = s_gradients4[gi10][0]*tempx + s_gradients4[gi10][1]*tempy + s_gradients4[gi10][2]*tempz + s_gradients4[gi10][3]*tempw; tempy = yc - y0; tempz = zc - (z0+1); - s[3] = gradient4[gi12][0]*tempx + gradient4[gi12][1]*tempy + gradient4[gi12][2]*tempz + gradient4[gi12][3]*tempw; + s[3] = s_gradients4[gi12][0]*tempx + s_gradients4[gi12][1]*tempy + s_gradients4[gi12][2]*tempz + s_gradients4[gi12][3]*tempw; tempx = xc - (x0+1); - t[3] = gradient4[gi13][0]*tempx + gradient4[gi13][1]*tempy + gradient4[gi13][2]*tempz + gradient4[gi13][3]*tempw; + t[3] = s_gradients4[gi13][0]*tempx + s_gradients4[gi13][1]*tempy + s_gradients4[gi13][2]*tempz + s_gradients4[gi13][3]*tempw; tempy = yc - (y0+1); - v[3] = gradient4[gi15][0]*tempx + gradient4[gi15][1]*tempy + gradient4[gi15][2]*tempz + gradient4[gi15][3]*tempw; + v[3] = s_gradients4[gi15][0]*tempx + s_gradients4[gi15][1]*tempy + s_gradients4[gi15][2]*tempz + s_gradients4[gi15][3]*tempw; tempx = xc - x0; - u[3] = gradient4[gi14][0]*tempx + gradient4[gi14][1]*tempy + gradient4[gi14][2]*tempz + gradient4[gi14][3]*tempw; + u[3] = s_gradients4[gi14][0]*tempx + s_gradients4[gi14][1]*tempy + s_gradients4[gi14][2]*tempz + s_gradients4[gi14][3]*tempw; Li1 = s[0] + Cx*(t[0]-s[0]); Li2 = u[0] + Cx*(v[0]-u[0]); diff --git a/src/Nazara/Noise/Simplex.cpp b/src/Nazara/Noise/Simplex.cpp index c93a226d4..c2ce28c3f 100644 --- a/src/Nazara/Noise/Simplex.cpp +++ b/src/Nazara/Noise/Simplex.cpp @@ -10,185 +10,95 @@ namespace Nz { - Simplex::Simplex() : - gradient2{ - {1,1},{-1,1},{1,-1},{-1,-1}, - {1,0},{-1,0},{0,1},{0,-1} - }, - gradient3{ - {1.f,1.f,0.f},{-1.f,1.f,0.f},{1.f,-1.f,0.f},{-1.f,-1.f,0.f}, - {1.f,0.f,1.f},{-1.f,0.f,1.f},{1.f,0.f,-1.f},{-1.f,0.f,-1.f}, - {0.f,1.f,1.f},{0.f,-1.f,1.f},{0.f,1.f,-1.f},{0.f,-1.f,-1.f} - }, - gradient4{ - {0.f,1.f,1.f,1.f}, {0.f,1.f,1.f,-1.f}, {0.f,1.f,-1.f,1.f}, {0.f,1.f,-1.f,-1.f}, - {0.f,-1.f,1.f,1.f},{0.f,-1.f,1.f,-1.f},{0.f,-1.f,-1.f,1.f},{0.f,-1.f,-1.f,-1.f}, - {1.f,0.f,1.f,1.f}, {1.f,0.f,1.f,-1.f}, {1.f,0.f,-1.f,1.f}, {1.f,0.f,-1.f,-1.f}, - {-1.f,0.f,1.f,1.f},{-1.f,0.f,1.f,-1.f},{-1.f,0.f,-1.f,1.f},{-1.f,0.f,-1.f,-1.f}, - {1.f,1.f,0.f,1.f}, {1.f,1.f,0.f,-1.f}, {1.f,-1.f,0.f,1.f}, {1.f,-1.f,0.f,-1.f}, - {-1.f,1.f,0.f,1.f},{-1.f,1.f,0.f,-1.f},{-1.f,-1.f,0.f,1.f},{-1.f,-1.f,0.f,-1.f}, - {1.f,1.f,1.f,0.f}, {1.f,1.f,-1.f,0.f}, {1.f,-1.f,1.f,0.f}, {1.f,-1.f,-1.f,0.f}, - {-1.f,1.f,1.f,0.f},{-1.f,1.f,-1.f,0.f},{-1.f,-1.f,1.f,0.f},{-1.f,-1.f,-1.f,0.f} - }, - lookupTable4D{ - {0,1,2,3},{0,1,3,2},{0,0,0,0},{0,2,3,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,2,3,0}, - {0,2,1,3},{0,0,0,0},{0,3,1,2},{0,3,2,1},{0,0,0,0},{0,0,0,0},{0,0,0,0},{1,3,2,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {1,2,0,3},{0,0,0,0},{1,3,0,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,3,0,1},{2,3,1,0}, - {1,0,2,3},{1,0,3,2},{0,0,0,0},{0,0,0,0},{0,0,0,0},{2,0,3,1},{0,0,0,0},{2,1,3,0}, - {0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}, - {2,0,1,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,0,1,2},{3,0,2,1},{0,0,0,0},{3,1,2,0}, - {2,1,0,3},{0,0,0,0},{0,0,0,0},{0,0,0,0},{3,1,0,2},{0,0,0,0},{3,2,0,1},{3,2,1,0} - }, - SkewCoeff2D (0.5f*(std::sqrt(3.f) - 1.f)), - UnskewCoeff2D((3.f-std::sqrt(3.f))/6.f), - SkewCoeff3D (1/3.f), - UnskewCoeff3D (1/6.f), - SkewCoeff4D ((std::sqrt(5.f) - 1.f)/4.f), - UnskewCoeff4D ((5.f - std::sqrt(5.f))/20.f) + namespace { - + constexpr float s_SkewCoeff2D = 0.5f * (M_SQRT3 - 1.f); + constexpr float s_UnskewCoeff2D = (3.f - M_SQRT3)/6.f; + constexpr float s_SkewCoeff3D = 1.f / 3.f; + constexpr float s_UnskewCoeff3D = 1.f / 6.f; + constexpr float s_SkewCoeff4D = (M_SQRT5 - 1.f)/4.f; + constexpr float s_UnskewCoeff4D = (5.f - M_SQRT5)/20.f; } - Simplex::Simplex(unsigned int seed) : Simplex() + Simplex::Simplex(unsigned int seed) { SetSeed(seed); Shuffle(); } - float Simplex::Get(std::initializer_list coordinates, float scale) const + float Simplex::Get(float x, float y, float scale) const { - switch(coordinates.size()) + float xc = x * scale; + float yc = y * scale; + + float sum = (xc + yc) * s_SkewCoeff2D; + Vector2i skewedCubeOrigin(fastfloor(xc + sum), fastfloor(yc + sum)); + + sum = (skewedCubeOrigin.x + skewedCubeOrigin.y) * s_UnskewCoeff2D; + Vector2f unskewedCubeOrigin(skewedCubeOrigin.x - sum, skewedCubeOrigin.y - sum); + + Vector2f unskewedDistToOrigin(xc - unskewedCubeOrigin.x, yc - unskewedCubeOrigin.y); + + Vector2f off1; + if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) + off1.Set(1, 0); + else + off1.Set(0, 1); + + std::array d; + d[0] = -unskewedDistToOrigin; + d[1] = d[0] + off1 - Vector2f(s_UnskewCoeff2D); + d[2] = d[0] + Vector2f(1.f - 2.f * s_UnskewCoeff2D); + + Vector2i offset(skewedCubeOrigin.x & 255, skewedCubeOrigin.y & 255); + std::array gi = { - case 2: - return this->_2D(coordinates,scale); - case 3: - return this->_3D(coordinates,scale); - case 4: - return this->_4D(coordinates,scale); - default: - throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4"); + m_permutations[offset.x + m_permutations[offset.y]] & 7, + m_permutations[offset.x + off1.x + m_permutations[offset.y + off1.y]] & 7, + m_permutations[offset.x + 1 + m_permutations[offset.y + 1]] & 7 + }; + + float n = 0.f; + for (unsigned int i = 0; i < 3; ++i) + { + float c = 0.5f - d[i].x * d[i].x - d[i].y *d[i].y; + if (c > 0.f) + n += c * c * c * c * (s_gradients2[gi[i]].x * d[i].x + s_gradients2[gi[i]].y * d[i].y); } + + return n*70.f; } - float Simplex::_2D(std::initializer_list coordinates, float scale) const + float Simplex::Get(float x, float y, float z, float scale) const { - thread_local float xc,yc; - thread_local int ii,jj; - thread_local int gi0,gi1,gi2; - thread_local int skewedCubeOriginx,skewedCubeOriginy; - thread_local int off1x,off1y; - thread_local float n1,n2,n3; - thread_local float c1,c2,c3; - thread_local float sum; - thread_local float unskewedCubeOriginx,unskewedCubeOriginy; - thread_local float unskewedDistToOriginx,unskewedDistToOriginy; - thread_local float d1x,d1y; - thread_local float d2x,d2y; - thread_local float d3x,d3y; + float xc, yc, zc; + int ii,jj,kk; + int gi0,gi1,gi2,gi3; + int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz; - std::initializer_list::const_iterator it = coordinates.begin(); + int off1x,off1y,off1z; + int off2x,off2y,off2z; + float n1,n2,n3,n4; + float c1,c2,c3,c4; - xc = *(it ) * scale; - yc = *(++it) * scale; - - sum = (xc + yc) * SkewCoeff2D; - skewedCubeOriginx = fastfloor(xc + sum); - skewedCubeOriginy = fastfloor(yc + sum); - - sum = (skewedCubeOriginx + skewedCubeOriginy) * UnskewCoeff2D; - unskewedCubeOriginx = skewedCubeOriginx - sum; - unskewedCubeOriginy = skewedCubeOriginy - sum; - - unskewedDistToOriginx = xc - unskewedCubeOriginx;// Difference with 3d and 4d - unskewedDistToOriginy = yc - unskewedCubeOriginy; - - if(unskewedDistToOriginx > unskewedDistToOriginy) - { - off1x = 1; - off1y = 0; - } - else - { - off1x = 0; - off1y = 1; - } - - d1x = - unskewedDistToOriginx; - d1y = - unskewedDistToOriginy; - - d2x = d1x + off1x - UnskewCoeff2D; - d2y = d1y + off1y - UnskewCoeff2D; - - d3x = d1x + 1.f - 2.f * UnskewCoeff2D; - d3y = d1y + 1.f - 2.f * UnskewCoeff2D; - - ii = skewedCubeOriginx & 255; - jj = skewedCubeOriginy & 255; - - gi0 = perm[ii + perm[jj ]] & 7; - gi1 = perm[ii + off1x + perm[jj + off1y ]] & 7; - gi2 = perm[ii + 1 + perm[jj + 1 ]] & 7; - - c1 = 0.5f - d1x * d1x - d1y * d1y; - c2 = 0.5f - d2x * d2x - d2y * d2y; - c3 = 0.5f - d3x * d3x - d3y * d3y; - - if(c1 < 0) - n1 = 0; - else - n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1x + gradient2[gi0][1] * d1y); - - if(c2 < 0) - n2 = 0; - else - n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2x + gradient2[gi1][1] * d2y); - - if(c3 < 0) - n3 = 0; - else - n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3x + gradient2[gi2][1] * d3y); - - return (n1+n2+n3)*70.f; - } - - float Simplex::_3D(std::initializer_list coordinates, float scale) const - { - thread_local float xc, yc, zc; - thread_local float x,y,z; - thread_local int ii,jj,kk; - thread_local int gi0,gi1,gi2,gi3; - thread_local int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz; - - thread_local int off1x,off1y,off1z; - thread_local int off2x,off2y,off2z; - thread_local float n1,n2,n3,n4; - thread_local float c1,c2,c3,c4; - - thread_local float sum; - thread_local float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz; - thread_local float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz; - thread_local float d1x,d1y,d1z; - thread_local float d2x,d2y,d2z; - thread_local float d3x,d3y,d3z; - thread_local float d4x,d4y,d4z; - - std::initializer_list::const_iterator it = coordinates.begin(); - - x = *(it ); - y = *(++it); - z = *(++it); + float sum; + float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz; + float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz; + float d1x,d1y,d1z; + float d2x,d2y,d2z; + float d3x,d3y,d3z; + float d4x,d4y,d4z; xc = x * scale; yc = y * scale; zc = z * scale; - sum = (xc + yc + zc) * SkewCoeff3D; + sum = (xc + yc + zc) * s_SkewCoeff3D; skewedCubeOriginx = fastfloor(xc + sum); skewedCubeOriginy = fastfloor(yc + sum); skewedCubeOriginz = fastfloor(zc + sum); - sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz) * UnskewCoeff3D; + sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz) * s_UnskewCoeff3D; unskewedCubeOriginx = skewedCubeOriginx - sum; unskewedCubeOriginy = skewedCubeOriginy - sum; unskewedCubeOriginz = skewedCubeOriginz - sum; @@ -262,26 +172,26 @@ namespace Nz d1y = unskewedDistToOriginy; d1z = unskewedDistToOriginz; - d2x = d1x - off1x + UnskewCoeff3D; - d2y = d1y - off1y + UnskewCoeff3D; - d2z = d1z - off1z + UnskewCoeff3D; + d2x = d1x - off1x + s_UnskewCoeff3D; + d2y = d1y - off1y + s_UnskewCoeff3D; + d2z = d1z - off1z + s_UnskewCoeff3D; - d3x = d1x - off2x + 2.f*UnskewCoeff3D; - d3y = d1y - off2y + 2.f*UnskewCoeff3D; - d3z = d1z - off2z + 2.f*UnskewCoeff3D; + d3x = d1x - off2x + 2.f*s_UnskewCoeff3D; + d3y = d1y - off2y + 2.f*s_UnskewCoeff3D; + d3z = d1z - off2z + 2.f*s_UnskewCoeff3D; - d4x = d1x - 1.f + 3.f*UnskewCoeff3D; - d4y = d1y - 1.f + 3.f*UnskewCoeff3D; - d4z = d1z - 1.f + 3.f*UnskewCoeff3D; + d4x = d1x - 1.f + 3.f*s_UnskewCoeff3D; + d4y = d1y - 1.f + 3.f*s_UnskewCoeff3D; + d4z = d1z - 1.f + 3.f*s_UnskewCoeff3D; ii = skewedCubeOriginx & 255; jj = skewedCubeOriginy & 255; kk = skewedCubeOriginz & 255; - gi0 = perm[ii + perm[jj + perm[kk ]]] % 12; - gi1 = perm[ii + off1x + perm[jj + off1y + perm[kk + off1z ]]] % 12; - gi2 = perm[ii + off2x + perm[jj + off2y + perm[kk + off2z ]]] % 12; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 ]]] % 12; + gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk ]]] % 12; + gi1 = m_permutations[ii + off1x + m_permutations[jj + off1y + m_permutations[kk + off1z ]]] % 12; + gi2 = m_permutations[ii + off2x + m_permutations[jj + off2y + m_permutations[kk + off2z ]]] % 12; + gi3 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 ]]] % 12; c1 = 0.6f - d1x * d1x - d1y * d1y - d1z * d1z; c2 = 0.6f - d2x * d2x - d2y * d2y - d2z * d2z; @@ -291,69 +201,75 @@ namespace Nz if(c1 < 0) n1 = 0; else - n1 = c1*c1*c1*c1*(gradient3[gi0][0] * d1x + gradient3[gi0][1] * d1y + gradient3[gi0][2] * d1z); + n1 = c1*c1*c1*c1*(s_gradients3[gi0][0] * d1x + s_gradients3[gi0][1] * d1y + s_gradients3[gi0][2] * d1z); if(c2 < 0) n2 = 0; else - n2 = c2*c2*c2*c2*(gradient3[gi1][0] * d2x + gradient3[gi1][1] * d2y + gradient3[gi1][2] * d2z); + n2 = c2*c2*c2*c2*(s_gradients3[gi1][0] * d2x + s_gradients3[gi1][1] * d2y + s_gradients3[gi1][2] * d2z); if(c3 < 0) n3 = 0; else - n3 = c3*c3*c3*c3*(gradient3[gi2][0] * d3x + gradient3[gi2][1] * d3y + gradient3[gi2][2] * d3z); + n3 = c3*c3*c3*c3*(s_gradients3[gi2][0] * d3x + s_gradients3[gi2][1] * d3y + s_gradients3[gi2][2] * d3z); if(c4 < 0) n4 = 0; else - n4 = c4*c4*c4*c4*(gradient3[gi3][0] * d4x + gradient3[gi3][1] * d4y + gradient3[gi3][2] * d4z); + n4 = c4*c4*c4*c4*(s_gradients3[gi3][0] * d4x + s_gradients3[gi3][1] * d4y + s_gradients3[gi3][2] * d4z); return (n1+n2+n3+n4)*32; } - float Simplex::_4D(std::initializer_list coordinates, float scale) const + float Simplex::Get(float x, float y, float z, float w, float scale) const { - thread_local float xc,yc,zc,wc; - thread_local float x,y,z,w; - thread_local int ii,jj,kk,ll; - thread_local int gi0,gi1,gi2,gi3,gi4; - thread_local int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz,skewedCubeOriginw; + static std::array lookupTable = + { + { + {0,1,2,3}, {0,1,3,2}, {0,0,0,0}, {0,2,3,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {1,2,3,0}, + {0,2,1,3}, {0,0,0,0}, {0,3,1,2}, {0,3,2,1}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {1,3,2,0}, + {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, + {1,2,0,3}, {0,0,0,0}, {1,3,0,2}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {2,3,0,1}, {2,3,1,0}, + {1,0,2,3}, {1,0,3,2}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {2,0,3,1}, {0,0,0,0}, {2,1,3,0}, + {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, + {2,0,1,3}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {3,0,1,2}, {3,0,2,1}, {0,0,0,0}, {3,1,2,0}, + {2,1,0,3}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {3,1,0,2}, {0,0,0,0}, {3,2,0,1}, {3,2,1,0} + } + }; - thread_local int off1x,off1y,off1z,off1w; - thread_local int off2x,off2y,off2z,off2w; - thread_local int off3x,off3y,off3z,off3w; + float xc,yc,zc,wc; + int ii,jj,kk,ll; + int gi0,gi1,gi2,gi3,gi4; + int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz,skewedCubeOriginw; - thread_local int c; - thread_local float n1,n2,n3,n4,n5; - thread_local float c1,c2,c3,c4,c5,c6; + int off1x,off1y,off1z,off1w; + int off2x,off2y,off2z,off2w; + int off3x,off3y,off3z,off3w; - thread_local float sum; - thread_local float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz,unskewedCubeOriginw; - thread_local float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz,unskewedDistToOriginw; - thread_local float d1x,d2x,d3x,d4x,d5x; - thread_local float d1y,d2y,d3y,d4y,d5y; - thread_local float d1z,d2z,d3z,d4z,d5z; - thread_local float d1w,d2w,d3w,d4w,d5w; + int c; + float n1,n2,n3,n4,n5; + float c1,c2,c3,c4,c5,c6; - std::initializer_list::const_iterator it = coordinates.begin(); - - x = *(it ); - y = *(++it); - z = *(++it); - w = *(++it); + float sum; + float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz,unskewedCubeOriginw; + float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz,unskewedDistToOriginw; + float d1x,d2x,d3x,d4x,d5x; + float d1y,d2y,d3y,d4y,d5y; + float d1z,d2z,d3z,d4z,d5z; + float d1w,d2w,d3w,d4w,d5w; xc = x * scale; yc = y * scale; zc = z * scale; wc = w * scale; - sum = (xc + yc + zc + wc) * SkewCoeff4D; + sum = (xc + yc + zc + wc) * s_SkewCoeff4D; skewedCubeOriginx = fastfloor(xc + sum); skewedCubeOriginy = fastfloor(yc + sum); skewedCubeOriginz = fastfloor(zc + sum); skewedCubeOriginw = fastfloor(wc + sum); - sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz + skewedCubeOriginw) * UnskewCoeff4D; + sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz + skewedCubeOriginw) * s_UnskewCoeff4D; unskewedCubeOriginx = skewedCubeOriginx - sum; unskewedCubeOriginy = skewedCubeOriginy - sum; unskewedCubeOriginz = skewedCubeOriginz - sum; @@ -372,56 +288,56 @@ namespace Nz c6 = (unskewedDistToOriginz > unskewedDistToOriginw) ? 1 : 0; c = c1 + c2 + c3 + c4 + c5 + c6; - off1x = lookupTable4D[c][0] >= 3 ? 1 : 0; - off1y = lookupTable4D[c][1] >= 3 ? 1 : 0; - off1z = lookupTable4D[c][2] >= 3 ? 1 : 0; - off1w = lookupTable4D[c][3] >= 3 ? 1 : 0; + off1x = lookupTable[c][0] >= 3 ? 1 : 0; + off1y = lookupTable[c][1] >= 3 ? 1 : 0; + off1z = lookupTable[c][2] >= 3 ? 1 : 0; + off1w = lookupTable[c][3] >= 3 ? 1 : 0; - off2x = lookupTable4D[c][0] >= 2 ? 1 : 0; - off2y = lookupTable4D[c][1] >= 2 ? 1 : 0; - off2z = lookupTable4D[c][2] >= 2 ? 1 : 0; - off2w = lookupTable4D[c][3] >= 2 ? 1 : 0; + off2x = lookupTable[c][0] >= 2 ? 1 : 0; + off2y = lookupTable[c][1] >= 2 ? 1 : 0; + off2z = lookupTable[c][2] >= 2 ? 1 : 0; + off2w = lookupTable[c][3] >= 2 ? 1 : 0; - off3x = lookupTable4D[c][0] >= 1 ? 1 : 0; - off3y = lookupTable4D[c][1] >= 1 ? 1 : 0; - off3z = lookupTable4D[c][2] >= 1 ? 1 : 0; - off3w = lookupTable4D[c][3] >= 1 ? 1 : 0; + off3x = lookupTable[c][0] >= 1 ? 1 : 0; + off3y = lookupTable[c][1] >= 1 ? 1 : 0; + off3z = lookupTable[c][2] >= 1 ? 1 : 0; + off3w = lookupTable[c][3] >= 1 ? 1 : 0; d1x = unskewedDistToOriginx; d1y = unskewedDistToOriginy; d1z = unskewedDistToOriginz; d1w = unskewedDistToOriginw; - d2x = d1x - off1x + UnskewCoeff4D; - d2y = d1y - off1y + UnskewCoeff4D; - d2z = d1z - off1z + UnskewCoeff4D; - d2w = d1w - off1w + UnskewCoeff4D; + d2x = d1x - off1x + s_UnskewCoeff4D; + d2y = d1y - off1y + s_UnskewCoeff4D; + d2z = d1z - off1z + s_UnskewCoeff4D; + d2w = d1w - off1w + s_UnskewCoeff4D; - d3x = d1x - off2x + 2.f*UnskewCoeff4D; - d3y = d1y - off2y + 2.f*UnskewCoeff4D; - d3z = d1z - off2z + 2.f*UnskewCoeff4D; - d3w = d1w - off2w + 2.f*UnskewCoeff4D; + d3x = d1x - off2x + 2.f*s_UnskewCoeff4D; + d3y = d1y - off2y + 2.f*s_UnskewCoeff4D; + d3z = d1z - off2z + 2.f*s_UnskewCoeff4D; + d3w = d1w - off2w + 2.f*s_UnskewCoeff4D; - d4x = d1x - off3x + 3.f*UnskewCoeff4D; - d4y = d1y - off3y + 3.f*UnskewCoeff4D; - d4z = d1z - off3z + 3.f*UnskewCoeff4D; - d4w = d1w - off3w + 3.f*UnskewCoeff4D; + d4x = d1x - off3x + 3.f*s_UnskewCoeff4D; + d4y = d1y - off3y + 3.f*s_UnskewCoeff4D; + d4z = d1z - off3z + 3.f*s_UnskewCoeff4D; + d4w = d1w - off3w + 3.f*s_UnskewCoeff4D; - d5x = d1x - 1.f + 4*UnskewCoeff4D; - d5y = d1y - 1.f + 4*UnskewCoeff4D; - d5z = d1z - 1.f + 4*UnskewCoeff4D; - d5w = d1w - 1.f + 4*UnskewCoeff4D; + d5x = d1x - 1.f + 4*s_UnskewCoeff4D; + d5y = d1y - 1.f + 4*s_UnskewCoeff4D; + d5z = d1z - 1.f + 4*s_UnskewCoeff4D; + d5w = d1w - 1.f + 4*s_UnskewCoeff4D; ii = skewedCubeOriginx & 255; jj = skewedCubeOriginy & 255; kk = skewedCubeOriginz & 255; ll = skewedCubeOriginw & 255; - gi0 = perm[ii + perm[jj + perm[kk + perm[ll ]]]] & 31; - gi1 = perm[ii + off1x + perm[jj + off1y + perm[kk + off1z + perm[ll + off1w]]]] & 31; - gi2 = perm[ii + off2x + perm[jj + off2y + perm[kk + off2z + perm[ll + off2w]]]] & 31; - gi3 = perm[ii + off3x + perm[jj + off3y + perm[kk + off3z + perm[ll + off3w]]]] & 31; - gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1 ]]]] % 32; + gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk + m_permutations[ll ]]]] & 31; + gi1 = m_permutations[ii + off1x + m_permutations[jj + off1y + m_permutations[kk + off1z + m_permutations[ll + off1w]]]] & 31; + gi2 = m_permutations[ii + off2x + m_permutations[jj + off2y + m_permutations[kk + off2z + m_permutations[ll + off2w]]]] & 31; + gi3 = m_permutations[ii + off3x + m_permutations[jj + off3y + m_permutations[kk + off3z + m_permutations[ll + off3w]]]] & 31; + gi4 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll + 1 ]]]] % 32; c1 = 0.6f - d1x*d1x - d1y*d1y - d1z*d1z - d1w*d1w; c2 = 0.6f - d2x*d2x - d2y*d2y - d2z*d2z - d2w*d2w; @@ -432,27 +348,27 @@ namespace Nz if(c1 < 0) n1 = 0; else - n1 = c1*c1*c1*c1*(gradient4[gi0][0]*d1x + gradient4[gi0][1]*d1y + gradient4[gi0][2]*d1z + gradient4[gi0][3]*d1w); + n1 = c1*c1*c1*c1*(s_gradients4[gi0][0]*d1x + s_gradients4[gi0][1]*d1y + s_gradients4[gi0][2]*d1z + s_gradients4[gi0][3]*d1w); if(c2 < 0) n2 = 0; else - n2 = c2*c2*c2*c2*(gradient4[gi1][0]*d2x + gradient4[gi1][1]*d2y + gradient4[gi1][2]*d2z + gradient4[gi1][3]*d2w); + n2 = c2*c2*c2*c2*(s_gradients4[gi1][0]*d2x + s_gradients4[gi1][1]*d2y + s_gradients4[gi1][2]*d2z + s_gradients4[gi1][3]*d2w); if(c3 < 0) n3 = 0; else - n3 = c3*c3*c3*c3*(gradient4[gi2][0]*d3x + gradient4[gi2][1]*d3y + gradient4[gi2][2]*d3z + gradient4[gi2][3]*d3w); + n3 = c3*c3*c3*c3*(s_gradients4[gi2][0]*d3x + s_gradients4[gi2][1]*d3y + s_gradients4[gi2][2]*d3z + s_gradients4[gi2][3]*d3w); if(c4 < 0) n4 = 0; else - n4 = c4*c4*c4*c4*(gradient4[gi3][0]*d4x + gradient4[gi3][1]*d4y + gradient4[gi3][2]*d4z + gradient4[gi3][3]*d4w); + n4 = c4*c4*c4*c4*(s_gradients4[gi3][0]*d4x + s_gradients4[gi3][1]*d4y + s_gradients4[gi3][2]*d4z + s_gradients4[gi3][3]*d4w); if(c5 < 0) n5 = 0; else - n5 = c5*c5*c5*c5*(gradient4[gi4][0]*d5x + gradient4[gi4][1]*d5y + gradient4[gi4][2]*d5z + gradient4[gi4][3]*d5w); + n5 = c5*c5*c5*c5*(s_gradients4[gi4][0]*d5x + s_gradients4[gi4][1]*d5y + s_gradients4[gi4][2]*d5z + s_gradients4[gi4][3]*d5w); return (n1+n2+n3+n4+n5)*27.f; } diff --git a/src/Nazara/Noise/Worley.cpp b/src/Nazara/Noise/Worley.cpp index 603820706..9d262f6b1 100644 --- a/src/Nazara/Noise/Worley.cpp +++ b/src/Nazara/Noise/Worley.cpp @@ -10,56 +10,38 @@ namespace Nz { - Worley::Worley() : - scales{ - 1.f / std::sqrt(2), - 0.5f / std::sqrt(2), - 0.5f / std::sqrt(2), - 0.5f / std::sqrt(2) - } + namespace + { + static constexpr std::array m_functionScales = + { + 1.f / M_SQRT2, + 0.5f / M_SQRT2, + 0.5f / M_SQRT2, + 0.5f / M_SQRT2 + }; + } + Worley::Worley() : + m_function(WorleyFunction_F1) { - function = WorleyFunction_F1; } - Worley::Worley(unsigned int seed) : Worley() + Worley::Worley(unsigned int seed) : + Worley() { SetSeed(seed); Shuffle(); } - void Worley::Set(WorleyFunction func) - { - function = func; - } - - float Worley::Get(std::initializer_list coordinates, float scale) const - { - switch(coordinates.size()) - { - case 2: - return this->_2D(coordinates,scale); - case 3: - return this->_3D(coordinates,scale); - case 4: - return this->_4D(coordinates,scale); - default: - throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4"); - } - } - - float Worley::_2D(std::initializer_list coordinates, float scale) const + float Worley::Get(float x, float y, float scale) const { std::map featurePoints; - std::map::iterator it; float xc, yc; int x0, y0; float fractx, fracty; - std::initializer_list::const_iterator c = coordinates.begin(); - - xc = *(c ) * scale; - yc = *(++c) * scale; + xc = x * scale; + yc = y * scale; x0 = fastfloor(xc); y0 = fastfloor(yc); @@ -69,83 +51,83 @@ namespace Nz featurePoints.clear(); - _SquareTest(x0,y0,xc,yc,featurePoints); + SquareTest(x0,y0,xc,yc,featurePoints); - it = featurePoints.begin(); - std::advance(it,function); + auto it = featurePoints.begin(); + std::advance(it, m_function); if(fractx < it->first) - _SquareTest(x0 - 1,y0,xc,yc,featurePoints); + SquareTest(x0 - 1,y0,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); if(1.f - fractx < it->first) - _SquareTest(x0 + 1,y0,xc,yc,featurePoints); + SquareTest(x0 + 1,y0,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); if(fracty < it->first) - _SquareTest(x0,y0 - 1,xc,yc,featurePoints); + SquareTest(x0,y0 - 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(1.f - fracty < it->first) - _SquareTest(x0,y0 + 1,xc,yc,featurePoints); + if (1.f - fracty < it->first) + SquareTest(x0,y0 + 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(fractx < it->first && - fracty < it->first) - _SquareTest(x0 - 1, y0 - 1,xc,yc,featurePoints); + if (fractx < it->first && fracty < it->first) + SquareTest(x0 - 1, y0 - 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(1.f - fractx < it->first && - fracty < it->first) - _SquareTest(x0 + 1, y0 - 1,xc,yc,featurePoints); + if (1.f - fractx < it->first && fracty < it->first) + SquareTest(x0 + 1, y0 - 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(fractx < it->first && - 1.f - fracty < it->first) - _SquareTest(x0 - 1, y0 + 1,xc,yc,featurePoints); + if (fractx < it->first && 1.f - fracty < it->first) + SquareTest(x0 - 1, y0 + 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - if(1.f - fractx < it->first && - 1.f - fracty < it->first) - _SquareTest(x0 + 1, y0 + 1,xc,yc,featurePoints); + if(1.f - fractx < it->first && 1.f - fracty < it->first) + SquareTest(x0 + 1, y0 + 1,xc,yc,featurePoints); it = featurePoints.begin(); - std::advance(it,function); + std::advance(it, m_function); - return it->first * scales[function]; + return it->first * m_functionScales[m_function]; } - float Worley::_3D(std::initializer_list coordinates, float scale) const + float Worley::Get(float x, float y, float z, float scale) const { throw std::runtime_error("Worley 3D not available yet."); } - float Worley::_4D(std::initializer_list coordinates, float scale) const + float Worley::Get(float x, float y, float z, float w, float scale) const { throw std::runtime_error("Worley 4D not available yet."); } + void Worley::Set(WorleyFunction func) + { + m_function = func; + } - void Worley::_SquareTest(int xi, int yi, float x, float y, std::map & featurePoints) const + void Worley::SquareTest(int xi, int yi, float x, float y, std::map& featurePoints) const { int ii = xi & 255; int jj = yi & 255; - int seed = perm[ii + perm[jj]]; + int seed = m_permutations[ii + m_permutations[jj]]; //On initialise notre rng avec seed std::minstd_rand0 randomNumberGenerator(seed);