diff --git a/include/Nazara/Noise/ComplexNoiseBase.hpp b/include/Nazara/Noise/ComplexNoiseBase.hpp new file mode 100644 index 000000000..e1f159e9f --- /dev/null +++ b/include/Nazara/Noise/ComplexNoiseBase.hpp @@ -0,0 +1,36 @@ +// Copyright (C) 2012 Rémi Bèges +// This file is part of the "Nazara Engine". +// For conditions of distribution and use, see copyright notice in Config.hpp + +#pragma once + +#ifndef COMPLEXNOISEBASE_H +#define COMPLEXNOISEBASE_H + +#include +//#include +#include "NoiseBase.hpp" + +class NzComplexNoiseBase : public NzNoiseBase +{ + public: + NzComplexNoiseBase(); + ~NzComplexNoiseBase(); + + void SetLacunarity(float lacunarity); + void SetHurstParameter(float h); + void SetOctavesNumber(float octaves); + void RecomputeExponentArray(); + + protected: + float m_lacunarity; + float m_hurst; + float m_octaves; + float exponent_array[30]; + float m_sum; + private: + bool m_parametersModified; + +}; + +#endif // COMPLEXNOISEBASE_H diff --git a/include/Nazara/Noise/Noise.hpp b/include/Nazara/Noise/Noise.hpp index c4925ac0a..61b062b5b 100644 --- a/include/Nazara/Noise/Noise.hpp +++ b/include/Nazara/Noise/Noise.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2012 AUTHORS +// Copyright (C) 2012 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp diff --git a/include/Nazara/Noise/NoiseBase.hpp b/include/Nazara/Noise/NoiseBase.hpp index 0bd37ab47..06f0d37ca 100644 --- a/include/Nazara/Noise/NoiseBase.hpp +++ b/include/Nazara/Noise/NoiseBase.hpp @@ -18,6 +18,7 @@ class NzNoiseBase void SetNewSeed(int seed); int GetUniformRandomValue(); void ShufflePermutationTable(); + int fastfloor(float n); int JenkinsHash(int a, int b, int c); protected: diff --git a/include/Nazara/Noise/NoiseMachine.hpp b/include/Nazara/Noise/NoiseMachine.hpp index 751c186c7..3be3cebe9 100644 --- a/include/Nazara/Noise/NoiseMachine.hpp +++ b/include/Nazara/Noise/NoiseMachine.hpp @@ -8,22 +8,20 @@ #define NOISEMACHINE_HPP #include -//#include -#include "NoiseBase.hpp" +//#include +#include "ComplexNoiseBase.hpp" #include #include #include -//TODO : tableau de gradients en float au lieu de int ? Ou condition ternaires ? -// utiliser fastfloor partout -// utiliser copies paramètres pour économiser mémoire -// améliorer le mélange de la table de perm +//TODO : AMELIORER MELANGE TABLE PERMUTATION +// PB MULTIPLES APPELS SHUFFLEPERMUTATIONTABLE() -class NzNoiseMachine : public NzNoiseBase +class NzNoiseMachine : public NzComplexNoiseBase { public: NzNoiseMachine(int seed = 0); - ~NzNoiseMachine(); + ~NzNoiseMachine() = default; float Get2DPerlinNoiseValue (float x, float y, float res); float Get3DPerlinNoiseValue (float x, float y, float z, float res); @@ -37,11 +35,6 @@ class NzNoiseMachine : public NzNoiseBase float Get3DCellNoiseValue(float x, float y, float z, float res); float Get4DCellNoiseValue(float x, float y, float z, float w, float res); - void SetLacunarity(float lacunarity); - void SetHurstParameter(float h); - void SetOctavesNumber(float octaves); - void RecomputeExponentArray(); - float Get2DFBMNoiseValue(float x, float y, float res); float Get3DFBMNoiseValue(float x, float y, float z, float res); @@ -59,11 +52,11 @@ class NzNoiseMachine : public NzNoiseBase //----------------------- Simplex variables -------------------------------------- float n1, n2, n3, n4, n5; - NzVector4f A; - NzVector4f d1,d2,d3,d4,d5; - NzVector4f IsoOriginDist; + NzVector4f d1,d2,d3,d4,d5,unskewedCubeOrigin,unskewedDistToOrigin; + NzVector4i off1, off2,off3,skewedCubeOrigin; + + NzVector4f A,IsoOriginDist; NzVector4i Origin; - NzVector4i off1, off2,off3; int ii,jj,kk,ll; int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15; @@ -86,20 +79,14 @@ class NzNoiseMachine : public NzNoiseBase float s[4],t[4],u[4],v[4]; float Cx, Cy, Cz, Cw; NzVector4f temp; - float nx,ny,nz,nw; float tmp; //---------------------- Complex Noise Variables -------------------------------- - float m_lacunarity; - float m_hurst; - float m_octaves; - bool m_parametersModified; - float exponent_array[30]; + bool first; float value; float remainder; - float m_sum; float smax; float smin; diff --git a/include/Nazara/Noise/Perlin2D.hpp b/include/Nazara/Noise/Perlin2D.hpp index 6b693fa23..614d7e6a1 100644 --- a/include/Nazara/Noise/Perlin2D.hpp +++ b/include/Nazara/Noise/Perlin2D.hpp @@ -27,8 +27,6 @@ template class NzPerlin2D : public NzNoiseBase T s,t,u,v; T Cx,Cy; T Li1, Li2; - T nx, ny; - T tmp; NzVector2 temp; }; diff --git a/include/Nazara/Noise/Perlin2D.inl b/include/Nazara/Noise/Perlin2D.inl index 2d84517fb..2225eb024 100644 --- a/include/Nazara/Noise/Perlin2D.inl +++ b/include/Nazara/Noise/Perlin2D.inl @@ -9,9 +9,8 @@ template NzPerlin2D::NzPerlin2D() { - T unit = 1.0/sqrt(2); - T grad2Temp[][2] = {{unit,unit},{-unit,unit},{unit,-unit},{-unit,-unit}, - {1,0},{-1,0},{0,1},{0,-1}}; + T grad2Temp[][2] = {{1,1},{-1,1},{1,-1},{-1,-1}, + {1,0},{-1,0},{0,1},{0,-1}}; for(int i(0) ; i < 8 ; ++i) for(int j(0) ; j < 2 ; ++j) @@ -21,11 +20,11 @@ NzPerlin2D::NzPerlin2D() template T NzPerlin2D::GetValue(T x, T y, T res) { - nx = x/res; - ny = y/res; + x /= res; + y /= res; - x0 = static_cast(nx); - y0 = static_cast(ny); + x0 = fastfloor(x); + y0 = fastfloor(y); ii = x0 & 255; jj = y0 & 255; @@ -35,31 +34,26 @@ T NzPerlin2D::GetValue(T x, T y, T res) gi2 = perm[ii + perm[jj + 1]] & 7; gi3 = perm[ii + 1 + perm[jj + 1]] & 7; - temp.x = nx-x0; - temp.y = ny-y0; + temp.x = x-x0; + temp.y = y-y0; + + Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); + Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); + s = gradient2[gi0][0]*temp.x + gradient2[gi0][1]*temp.y; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t = gradient2[gi1][0]*temp.x + gradient2[gi1][1]*temp.y; - temp.x = nx-x0; - temp.y = ny-(y0+1); - u = gradient2[gi2][0]*temp.x + gradient2[gi2][1]*temp.y; - - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.y = y-(y0+1); v = gradient2[gi3][0]*temp.x + gradient2[gi3][1]*temp.y; - tmp = nx-x0; - Cx = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); + temp.x = x-x0; + u = gradient2[gi2][0]*temp.x + gradient2[gi2][1]*temp.y; Li1 = s + Cx*(t-s); Li2 = u + Cx*(v-u); - tmp = ny - y0; - Cy = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); - return Li1 + Cy*(Li2-Li1); } diff --git a/include/Nazara/Noise/Perlin3D.inl b/include/Nazara/Noise/Perlin3D.inl index 99f3334e9..8e30f5a69 100644 --- a/include/Nazara/Noise/Perlin3D.inl +++ b/include/Nazara/Noise/Perlin3D.inl @@ -24,78 +24,68 @@ NzPerlin3D::NzPerlin3D() template T NzPerlin3D::GetValue(T x, T y, T z, T res) { - nx = x/res; - ny = y/res; - nz = z/res; + x /= res; + y /= res; + z /= res; - x0 = static_cast(nx); - y0 = static_cast(ny); - z0 = static_cast(nz); + x0 = fastfloor(x); + y0 = fastfloor(y); + z0 = fastfloor(z); ii = x0 & 255; jj = y0 & 255; kk = z0 & 255; - gi0 = perm[ii + perm[jj + perm[kk]]] % 16; - gi1 = perm[ii + 1 + perm[jj + perm[kk]]] % 16; - gi2 = perm[ii + perm[jj + 1 + perm[kk]]] % 16; - gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] % 16; + 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; - gi4 = perm[ii + perm[jj + perm[kk + 1]]] % 16; - gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] % 16; - gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] % 16; - gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] % 16; + 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; + + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-z0; + + Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); + Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); + Cz = temp.z * temp.z * temp.z * (temp.z * (temp.z * 6 - 15) + 10); - temp.x = nx-x0; - temp.y = ny-y0; - temp.z = nz-z0; s[0] = gradient3[gi0][0]*temp.x + gradient3[gi0][1]*temp.y + gradient3[gi0][2]*temp.z; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t[0] = gradient3[gi1][0]*temp.x + gradient3[gi1][1]*temp.y + gradient3[gi1][2]*temp.z; - temp.x = nx-x0; - temp.y = ny-(y0+1); - u[0] = gradient3[gi2][0]*temp.x + gradient3[gi2][1]*temp.y + gradient3[gi2][2]*temp.z; - - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.y = y-(y0+1); v[0] = gradient3[gi3][0]*temp.x + gradient3[gi3][1]*temp.y + gradient3[gi3][2]*temp.z; - temp.x = nx-x0; - temp.y = ny-y0; - temp.z = nz-(z0+1); + temp.x = x-x0; + u[0] = gradient3[gi2][0]*temp.x + gradient3[gi2][1]*temp.y + gradient3[gi2][2]*temp.z; + + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-(z0+1); s[1] = gradient3[gi4][0]*temp.x + gradient3[gi4][1]*temp.y + gradient3[gi4][2]*temp.z; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t[1] = gradient3[gi5][0]*temp.x + gradient3[gi5][1]*temp.y + gradient3[gi5][2]*temp.z; - temp.x = nx-x0; - temp.y = ny-(y0+1); - u[1] = gradient3[gi6][0]*temp.x + gradient3[gi6][1]*temp.y + gradient3[gi6][2]*temp.z; - - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.y = y-(y0+1); v[1] = gradient3[gi7][0]*temp.x + gradient3[gi7][1]*temp.y + gradient3[gi7][2]*temp.z; - tmp = nx-x0; - Cx = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); + temp.x = x-x0; + u[1] = gradient3[gi6][0]*temp.x + gradient3[gi6][1]*temp.y + gradient3[gi6][2]*temp.z; Li1 = s[0] + Cx*(t[0]-s[0]); Li2 = u[0] + Cx*(v[0]-u[0]); Li3 = s[1] + Cx*(t[1]-s[1]); Li4 = u[1] + Cx*(v[1]-u[1]); - tmp = ny-y0; - Cy = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); - Li5 = Li1 + Cy*(Li2-Li1); Li6 = Li3 + Cy*(Li4-Li3); - tmp = nz-z0; - Cz = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); - return Li5 + Cz*(Li6-Li5); } diff --git a/include/Nazara/Noise/Perlin4D.inl b/include/Nazara/Noise/Perlin4D.inl index 5df9b6a43..2ad741d8d 100644 --- a/include/Nazara/Noise/Perlin4D.inl +++ b/include/Nazara/Noise/Perlin4D.inl @@ -34,10 +34,10 @@ T NzPerlin4D::GetValue(T x, T y, T z, T w, T res) nz = z/res; nw = w/res; - x0 = static_cast(nx); - y0 = static_cast(ny); - z0 = static_cast(nz); - w0 = static_cast(nw); + x0 = fastfloor(nx); + y0 = fastfloor(ny); + z0 = fastfloor(nz); + w0 = fastfloor(nw); ii = x0 & 255; jj = y0 & 255; diff --git a/include/Nazara/Noise/Simplex2D.hpp b/include/Nazara/Noise/Simplex2D.hpp index 8d2221c09..e292587df 100644 --- a/include/Nazara/Noise/Simplex2D.hpp +++ b/include/Nazara/Noise/Simplex2D.hpp @@ -23,13 +23,13 @@ template class NzSimplex2D : public NzNoiseBase private: int ii,jj; int gi0,gi1,gi2; - NzVector2i Origin,off1; + NzVector2i skewedCubeOrigin,off1; T n1,n2,n3; T c1,c2,c3; T gradient2[8][2]; T UnskewCoeff2D; T SkewCoeff2D; - NzVector2 A, IsoOriginDist; + NzVector2 unskewedCubeOrigin, unskewedDistToOrigin; NzVector2 d1,d2,d3; diff --git a/include/Nazara/Noise/Simplex2D.inl b/include/Nazara/Noise/Simplex2D.inl index 1b3ac9311..3479c13f3 100644 --- a/include/Nazara/Noise/Simplex2D.inl +++ b/include/Nazara/Noise/Simplex2D.inl @@ -9,10 +9,8 @@ template NzSimplex2D::NzSimplex2D() { - - T unit = 1.0/sqrt(2); - T grad2Temp[][2] = {{unit,unit},{-unit,unit},{unit,-unit},{-unit,-unit}, - {1,0},{-1,0},{0,1},{0,-1}}; + T grad2Temp[][2] = {{1,1},{-1,1},{1,-1},{-1,-1}, + {1,0},{-1,0},{0,1},{0,-1}}; for(int i(0) ; i < 8 ; ++i) for(int j(0) ; j < 2 ; ++j) @@ -28,16 +26,16 @@ T NzSimplex2D::GetValue(T x, T y, T res) x /= res; y /= res; - Origin.x = fastfloor(x + (x + y) * SkewCoeff2D); - Origin.y = fastfloor(y + (x + y) * SkewCoeff2D); + skewedCubeOrigin.x = fastfloor(x + (x + y) * SkewCoeff2D); + skewedCubeOrigin.y = fastfloor(y + (x + y) * SkewCoeff2D); - A.x = Origin.x - (Origin.x + Origin.y) * UnskewCoeff2D; - A.y = Origin.y - (Origin.x + Origin.y) * UnskewCoeff2D; + unskewedCubeOrigin.x = skewedCubeOrigin.x - (skewedCubeOrigin.x + skewedCubeOrigin.y) * UnskewCoeff2D; + unskewedCubeOrigin.y = skewedCubeOrigin.y - (skewedCubeOrigin.x + skewedCubeOrigin.y) * UnskewCoeff2D; - IsoOriginDist.x = x - A.x; - IsoOriginDist.y = y - A.y; + unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; + unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - if(IsoOriginDist.x > IsoOriginDist.y) + if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) { off1.x = 1; off1.y = 0; @@ -48,8 +46,9 @@ T NzSimplex2D::GetValue(T x, T y, T res) off1.y = 1; } - d1.x = A.x - x; - d1.y = A.y - y; + + d1.x = unskewedCubeOrigin.x - x; + d1.y = unskewedCubeOrigin.y - y; d2.x = d1.x + off1.x - UnskewCoeff2D; d2.y = d1.y + off1.y - UnskewCoeff2D; @@ -57,32 +56,32 @@ T NzSimplex2D::GetValue(T x, T y, T res) d3.x = d1.x + 1.0 - 2 * UnskewCoeff2D; d3.y = d1.y + 1.0 - 2 * UnskewCoeff2D; - ii = Origin.x & 255; - jj = Origin.y & 255; + ii = skewedCubeOrigin.x & 255; + jj = skewedCubeOrigin.y & 255; - gi0 = perm[ii + perm[jj]] % 8; - gi1 = perm[ii + off1.x + perm[jj + off1.y]] % 8; - gi2 = perm[ii + 1 + perm[jj + 1]] % 8; - - n1 = gradient2[gi0][0] * d1.x + gradient2[gi0][1] * d1.y; - n2 = gradient2[gi1][0] * d2.x + gradient2[gi1][1] * d2.y; - n3 = gradient2[gi2][0] * d3.x + gradient2[gi2][1] * d3.y; + gi0 = perm[ii + perm[jj]] & 7; + gi1 = perm[ii + off1.x + perm[jj + off1.y]] & 7; + gi2 = perm[ii + 1 + perm[jj + 1]] & 7; c1 = 0.5 - d1.x * d1.x - d1.y * d1.y; c2 = 0.5 - d2.x * d2.x - d2.y * d2.y; c3 = 0.5 - d3.x * d3.x - d3.y * d3.y; if(c1 < 0) - c1 = 0; + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1.x + gradient2[gi0][1] * d1.y); + if(c2 < 0) - c2 = 0; + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2.x + gradient2[gi1][1] * d2.y); + if(c3 < 0) - c3 = 0; + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3.x + gradient2[gi2][1] * d3.y); - n1 = c1*c1*c1*n1; - n2 = c2*c2*c2*n2; - n3 = c3*c3*c3*n3; - - return (n1+n2+n3)*23.2; + return (n1+n2+n3)*70; } diff --git a/src/Nazara/Noise/ComplexNoiseBase.cpp b/src/Nazara/Noise/ComplexNoiseBase.cpp new file mode 100644 index 000000000..cd0288c3d --- /dev/null +++ b/src/Nazara/Noise/ComplexNoiseBase.cpp @@ -0,0 +1,61 @@ +#include "ComplexNoiseBase.hpp" +#include + +NzComplexNoiseBase::NzComplexNoiseBase() +{ + m_parametersModified = true; + m_lacunarity = 5.0f; + m_hurst = 1.2f; + m_octaves = 3.0f; +} + +void NzComplexNoiseBase::SetLacunarity(float lacunarity) +{ + if(lacunarity != m_lacunarity) + { + m_lacunarity = lacunarity; + m_parametersModified = true; + } +} + +void NzComplexNoiseBase::SetHurstParameter(float h) +{ + if(h != m_hurst) + { + m_hurst = h; + m_parametersModified = true; + } +} + +void NzComplexNoiseBase::SetOctavesNumber(float octaves) +{ + if(octaves != m_octaves && octaves < 30) + { + m_octaves = octaves; + m_parametersModified = true; + } +} + +void NzComplexNoiseBase::RecomputeExponentArray() +{ + if(m_parametersModified) + { + float frequency = 1.0; + m_sum = 0.f; + for (int i(0) ; i < m_octaves; ++i) + { + exponent_array[i] = std::pow( frequency, -m_hurst ); + frequency *= m_lacunarity; + + m_sum += exponent_array[i]; + + } + m_parametersModified = false; + } +} + + +NzComplexNoiseBase::~NzComplexNoiseBase() +{ + //dtor +} diff --git a/src/Nazara/Noise/Noise.cpp b/src/Nazara/Noise/Noise.cpp index c72266759..06c7c13af 100644 --- a/src/Nazara/Noise/Noise.cpp +++ b/src/Nazara/Noise/Noise.cpp @@ -1,9 +1,9 @@ -// Copyright (C) 2012 AUTHORS +// Copyright (C) 2012 Rémi Bèges // This file is part of the "Nazara Engine". // For conditions of distribution and use, see copyright notice in Config.hpp #include -#include +#include #include #include diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp index f864ad6ac..2f9b76b2d 100644 --- a/src/Nazara/Noise/NoiseBase.cpp +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -41,7 +41,7 @@ void NzNoiseBase::ShufflePermutationTable() int xchanger; unsigned int ncase; - for(int j(0) ; j < 10 ; ++j) + for(int j(0) ; j < 20 ; ++j) for (int i(0); i < 256 ; ++i) { ncase = this->GetUniformRandomValue() & 255; @@ -56,10 +56,7 @@ void NzNoiseBase::ShufflePermutationTable() int NzNoiseBase::fastfloor(float n) { - if(n >= 0) - return static_cast(n); - else - return static_cast(n-1); + return (n >= 0) ? static_cast(n) : static_cast(n-1); } int NzNoiseBase::JenkinsHash(int a, int b, int c) diff --git a/src/Nazara/Noise/NoiseMachine.cpp b/src/Nazara/Noise/NoiseMachine.cpp index 2b2b42fc5..476ba3e3f 100644 --- a/src/Nazara/Noise/NoiseMachine.cpp +++ b/src/Nazara/Noise/NoiseMachine.cpp @@ -35,8 +35,7 @@ NzNoiseMachine::NzNoiseMachine(int seed) for(int j(0) ; j < 4 ; ++j) lookupTable4D[i][j] = lookupTemp4D[i][j]; - float unit = 1.0/sqrt(2); - float grad2Temp[][2] = {{unit,unit},{-unit,unit},{unit,-unit},{-unit,-unit}, + float grad2Temp[][2] = {{1,1},{-1,1},{1,-1},{-1,-1}, {1,0},{-1,0},{0,1},{0,-1}}; for(int i(0) ; i < 8 ; ++i) @@ -69,28 +68,17 @@ NzNoiseMachine::NzNoiseMachine(int seed) for(int i(0) ; i < 32 ; ++i) for(int j(0) ; j < 4 ; ++j) gradient4[i][j] = grad4Temp[i][j]; - - m_lacunarity = 2.5f; - m_octaves = 3.0f; - m_hurst = 1.1f; - m_parametersModified = true; } -NzNoiseMachine::~NzNoiseMachine() -{ -} - - - //------------------------------ PERLIN ------------------------------ float NzNoiseMachine::Get2DPerlinNoiseValue(float x, float y, float res) { - nx = x/res; - ny = y/res; + x /= res; + y /= res; - x0 = static_cast(nx); - y0 = static_cast(ny); + x0 = fastfloor(x); + y0 = fastfloor(y); ii = x0 & 255; jj = y0 & 255; @@ -100,42 +88,37 @@ float NzNoiseMachine::Get2DPerlinNoiseValue(float x, float y, float res) gi2 = perm[ii + perm[jj + 1]] & 7; gi3 = perm[ii + 1 + perm[jj + 1]] & 7; - temp.x = nx-x0; - temp.y = ny-y0; + temp.x = x-x0; + temp.y = y-y0; + + Cx = temp.x * temp.x * temp.x * (temp.x * (temp.x * 6 - 15) + 10); + Cy = temp.y * temp.y * temp.y * (temp.y * (temp.y * 6 - 15) + 10); + s[0] = gradient2[gi0][0]*temp.x + gradient2[gi0][1]*temp.y; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t[0] = gradient2[gi1][0]*temp.x + gradient2[gi1][1]*temp.y; - temp.x = nx-x0; - temp.y = ny-(y0+1); - u[0] = gradient2[gi2][0]*temp.x + gradient2[gi2][1]*temp.y; - - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.y = y-(y0+1); v[0] = gradient2[gi3][0]*temp.x + gradient2[gi3][1]*temp.y; - tmp = nx-x0; - Cx = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); + temp.x = x-x0; + u[0] = gradient2[gi2][0]*temp.x + gradient2[gi2][1]*temp.y; Li1 = s[0] + Cx*(t[0]-s[0]); Li2 = u[0] + Cx*(v[0]-u[0]); - tmp = ny - y0; - Cy = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); - return Li1 + Cy*(Li2-Li1); } float NzNoiseMachine::Get3DPerlinNoiseValue(float x, float y, float z, float res) { - nx = x/res; - ny = y/res; - nz = z/res; + x /= res; + y /= res; + z /= res; - x0 = static_cast(nx); - y0 = static_cast(ny); - z0 = static_cast(nz); + x0 = static_cast(x); + y0 = static_cast(y); + z0 = static_cast(z); ii = x0 & 255; jj = y0 & 255; @@ -151,41 +134,38 @@ float NzNoiseMachine::Get3DPerlinNoiseValue(float x, float y, float z, float res gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] % 16; gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] % 16; - temp.x = nx-x0; - temp.y = ny-y0; - temp.z = nz-z0; + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-z0; s[0] = gradient3[gi0][0]*temp.x + gradient3[gi0][1]*temp.y + gradient3[gi0][2]*temp.z; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t[0] = gradient3[gi1][0]*temp.x + gradient3[gi1][1]*temp.y + gradient3[gi1][2]*temp.z; - temp.x = nx-x0; - temp.y = ny-(y0+1); + temp.x = x-x0; + temp.y = y-(y0+1); u[0] = gradient3[gi2][0]*temp.x + gradient3[gi2][1]*temp.y + gradient3[gi2][2]*temp.z; - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.x = x-(x0+1); v[0] = gradient3[gi3][0]*temp.x + gradient3[gi3][1]*temp.y + gradient3[gi3][2]*temp.z; - temp.x = nx-x0; - temp.y = ny-y0; - temp.z = nz-(z0+1); + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-(z0+1); s[1] = gradient3[gi4][0]*temp.x + gradient3[gi4][1]*temp.y + gradient3[gi4][2]*temp.z; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t[1] = gradient3[gi5][0]*temp.x + gradient3[gi5][1]*temp.y + gradient3[gi5][2]*temp.z; - temp.x = nx-x0; - temp.y = ny-(y0+1); + temp.x = x-x0; + temp.y = y-(y0+1); u[1] = gradient3[gi6][0]*temp.x + gradient3[gi6][1]*temp.y + gradient3[gi6][2]*temp.z; - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.x = x-(x0+1); + temp.y = y-(y0+1); v[1] = gradient3[gi7][0]*temp.x + gradient3[gi7][1]*temp.y + gradient3[gi7][2]*temp.z; - tmp = nx-x0; + tmp = x-x0; Cx = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); Li1 = s[0] + Cx*(t[0]-s[0]); @@ -193,13 +173,13 @@ float NzNoiseMachine::Get3DPerlinNoiseValue(float x, float y, float z, float res Li3 = s[1] + Cx*(t[1]-s[1]); Li4 = u[1] + Cx*(v[1]-u[1]); - tmp = ny-y0; + tmp = y-y0; Cy = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); Li5 = Li1 + Cy*(Li2-Li1); Li6 = Li3 + Cy*(Li4-Li3); - tmp = nz-z0; + tmp = z-z0; Cz = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); return Li5 + Cz*(Li6-Li5); @@ -207,15 +187,15 @@ float NzNoiseMachine::Get3DPerlinNoiseValue(float x, float y, float z, float res float NzNoiseMachine::Get4DPerlinNoiseValue(float x, float y, float z, float w, float res) { - nx = x/res; - ny = y/res; - nz = z/res; - nw = w/res; + x /= res; + y /= res; + z /= res; + w /= res; - x0 = static_cast(nx); - y0 = static_cast(ny); - z0 = static_cast(nz); - w0 = static_cast(nw); + x0 = static_cast(x); + y0 = static_cast(y); + z0 = static_cast(z); + w0 = static_cast(w); ii = x0 & 255; jj = y0 & 255; @@ -242,77 +222,69 @@ float NzNoiseMachine::Get4DPerlinNoiseValue(float x, float y, float z, float w, gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32; - temp.x = nx-x0; - temp.y = ny-y0; - temp.z = nz-z0; - temp.w = nw-w0; + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-z0; + temp.w = w-w0; s[0] = gradient4[gi0][0]*temp.x + gradient4[gi0][1]*temp.y + gradient4[gi0][2]*temp.z + gradient4[gi0][3]*temp.w; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t[0] = gradient4[gi1][0]*temp.x + gradient4[gi1][1]*temp.y + gradient4[gi1][2]*temp.z + gradient4[gi1][3]*temp.w; - temp.x = nx-x0; - temp.y = ny-(y0+1); + temp.x = x-x0; + temp.y = y-(y0+1); u[0] = gradient4[gi2][0]*temp.x + gradient4[gi2][1]*temp.y + gradient4[gi2][2]*temp.z + gradient4[gi2][3]*temp.w; - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.x = x-(x0+1); v[0] = gradient4[gi3][0]*temp.x + gradient4[gi3][1]*temp.y + gradient4[gi3][2]*temp.z + gradient4[gi3][3]*temp.w; - temp.x = nx-x0; - temp.y = ny-y0; - temp.z = nz-(z0+1); + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-(z0+1); s[1] = gradient4[gi4][0]*temp.x + gradient4[gi4][1]*temp.y + gradient4[gi4][2]*temp.z + gradient4[gi4][3]*temp.w; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t[1] = gradient4[gi5][0]*temp.x + gradient4[gi5][1]*temp.y + gradient4[gi5][2]*temp.z + gradient4[gi5][3]*temp.w; - temp.x = nx-x0; - temp.y = ny-(y0+1); + temp.x = x-x0; + temp.y = y-(y0+1); u[1] = gradient4[gi6][0]*temp.x + gradient4[gi6][1]*temp.y + gradient4[gi6][2]*temp.z + gradient4[gi6][3]*temp.w; - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.x = x-(x0+1); v[1] = gradient4[gi7][0]*temp.x + gradient4[gi7][1]*temp.y + gradient4[gi7][2]*temp.z + gradient4[gi7][3]*temp.w; - temp.x = nx-x0; - temp.y = ny-y0; - temp.z = nz-z0; - temp.w = nw-(w0+1); + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-z0; + temp.w = w-(w0+1); s[2] = gradient4[gi8][0]*temp.x + gradient4[gi8][1]*temp.y + gradient4[gi8][2]*temp.z + gradient4[gi8][3]*temp.w; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t[2] = gradient4[gi9][0]*temp.x + gradient4[gi9][1]*temp.y + gradient4[gi9][2]*temp.z + gradient4[gi9][3]*temp.w; - temp.x = nx-x0; - temp.y = ny-(y0+1); + temp.x = x-x0; + temp.y = y-(y0+1); u[2] = gradient4[gi10][0]*temp.x + gradient4[gi10][1]*temp.y + gradient4[gi10][2]*temp.z + gradient4[gi10][3]*temp.w; - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.x = x-(x0+1); v[2] = gradient4[gi11][0]*temp.x + gradient4[gi11][1]*temp.y + gradient4[gi11][2]*temp.z + gradient4[gi11][3]*temp.w; - temp.x = nx-x0; - temp.y = ny-y0; - temp.z = nz-(z0+1); + temp.x = x-x0; + temp.y = y-y0; + temp.z = z-(z0+1); s[3] = gradient4[gi12][0]*temp.x + gradient4[gi12][1]*temp.y + gradient4[gi12][2]*temp.z + gradient4[gi12][3]*temp.w; - temp.x = nx-(x0+1); - temp.y = ny-y0; + temp.x = x-(x0+1); t[3] = gradient4[gi13][0]*temp.x + gradient4[gi13][1]*temp.y + gradient4[gi13][2]*temp.z + gradient4[gi13][3]*temp.w; - temp.x = nx-x0; - temp.y = ny-(y0+1); + temp.x = x-x0; + temp.y = y-(y0+1); u[3] = gradient4[gi14][0]*temp.x + gradient4[gi14][1]*temp.y + gradient4[gi14][2]*temp.z + gradient4[gi14][3]*temp.w; - temp.x = nx-(x0+1); - temp.y = ny-(y0+1); + temp.x = x-(x0+1); v[3] = gradient4[gi15][0]*temp.x + gradient4[gi15][1]*temp.y + gradient4[gi15][2]*temp.z + gradient4[gi15][3]*temp.w; - tmp = nx-x0; + tmp = x-x0; Cx = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); Li1 = s[0] + Cx*(t[0]-s[0]); @@ -324,7 +296,7 @@ float NzNoiseMachine::Get4DPerlinNoiseValue(float x, float y, float z, float w, Li7 = s[3] + Cx*(t[3]-s[3]); Li8 = u[3] + Cx*(v[3]-u[3]); - tmp = ny-y0; + tmp = y-y0; Cy = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); Li9 = Li1 + Cy*(Li2-Li1); @@ -332,13 +304,13 @@ float NzNoiseMachine::Get4DPerlinNoiseValue(float x, float y, float z, float w, Li11 = Li5 + Cy*(Li6-Li5); Li12 = Li7 + Cy*(Li8-Li7); - tmp = nz-z0; + tmp = z-z0; Cz = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); Li13 = Li9 + Cz*(Li10-Li9); Li14 = Li11 + Cz*(Li12-Li11); - tmp = nw-w0; + tmp = w-w0; Cw = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); return Li13 + Cw*(Li14-Li13); @@ -351,17 +323,16 @@ float NzNoiseMachine::Get2DSimplexNoiseValue(float x, float y, float res) x /= res; y /= res; + skewedCubeOrigin.x = fastfloor(x + (x + y) * SkewCoeff2D); + skewedCubeOrigin.y = fastfloor(y + (x + y) * SkewCoeff2D); - Origin.x = fastfloor(x + (x + y) * SkewCoeff2D); - Origin.y = fastfloor(y + (x + y) * SkewCoeff2D); + unskewedCubeOrigin.x = skewedCubeOrigin.x - (skewedCubeOrigin.x + skewedCubeOrigin.y) * UnskewCoeff2D; + unskewedCubeOrigin.y = skewedCubeOrigin.y - (skewedCubeOrigin.x + skewedCubeOrigin.y) * UnskewCoeff2D; - A.x = Origin.x - (Origin.x + Origin.y) * UnskewCoeff2D; - A.y = Origin.y - (Origin.x + Origin.y) * UnskewCoeff2D; + unskewedDistToOrigin.x = x - unskewedCubeOrigin.x; + unskewedDistToOrigin.y = y - unskewedCubeOrigin.y; - IsoOriginDist.x = x - A.x; - IsoOriginDist.y = y - A.y; - - if(IsoOriginDist.x > IsoOriginDist.y) + if(unskewedDistToOrigin.x > unskewedDistToOrigin.y) { off1.x = 1; off1.y = 0; @@ -372,8 +343,9 @@ float NzNoiseMachine::Get2DSimplexNoiseValue(float x, float y, float res) off1.y = 1; } - d1.x = A.x - x; - d1.y = A.y - y; + + d1.x = unskewedCubeOrigin.x - x; + d1.y = unskewedCubeOrigin.y - y; d2.x = d1.x + off1.x - UnskewCoeff2D; d2.y = d1.y + off1.y - UnskewCoeff2D; @@ -381,33 +353,33 @@ float NzNoiseMachine::Get2DSimplexNoiseValue(float x, float y, float res) d3.x = d1.x + 1.0 - 2 * UnskewCoeff2D; d3.y = d1.y + 1.0 - 2 * UnskewCoeff2D; - ii = Origin.x & 255; - jj = Origin.y & 255; + ii = skewedCubeOrigin.x & 255; + jj = skewedCubeOrigin.y & 255; - gi0 = perm[ii + perm[jj]] % 8; - gi1 = perm[ii + off1.x + perm[jj + off1.y]] % 8; - gi2 = perm[ii + 1 + perm[jj + 1]] % 8; - - n1 = gradient2[gi0][0] * d1.x + gradient2[gi0][1] * d1.y; - n2 = gradient2[gi1][0] * d2.x + gradient2[gi1][1] * d2.y; - n3 = gradient2[gi2][0] * d3.x + gradient2[gi2][1] * d3.y; + gi0 = perm[ii + perm[jj]] & 7; + gi1 = perm[ii + off1.x + perm[jj + off1.y]] & 7; + gi2 = perm[ii + 1 + perm[jj + 1]] & 7; c1 = 0.5 - d1.x * d1.x - d1.y * d1.y; c2 = 0.5 - d2.x * d2.x - d2.y * d2.y; c3 = 0.5 - d3.x * d3.x - d3.y * d3.y; if(c1 < 0) - c1 = 0; + n1 = 0; + else + n1 = c1*c1*c1*c1*(gradient2[gi0][0] * d1.x + gradient2[gi0][1] * d1.y); + if(c2 < 0) - c2 = 0; + n2 = 0; + else + n2 = c2*c2*c2*c2*(gradient2[gi1][0] * d2.x + gradient2[gi1][1] * d2.y); + if(c3 < 0) - c3 = 0; + n3 = 0; + else + n3 = c3*c3*c3*c3*(gradient2[gi2][0] * d3.x + gradient2[gi2][1] * d3.y); - n1 = c1*c1*c1*n1; - n2 = c2*c2*c2*n2; - n3 = c3*c3*c3*n3; - - return (n1+n2+n3)*23.2; + return (n1+n2+n3)*70; } float NzNoiseMachine::Get3DSimplexNoiseValue(float x, float y, float z, float res) @@ -688,51 +660,6 @@ float NzNoiseMachine::Get4DCellNoiseValue(float x, float y, float z, float w, fl return 0; } -void NzNoiseMachine::SetLacunarity(float lacunarity) -{ - if(lacunarity != m_lacunarity) - { - m_lacunarity = lacunarity; - m_parametersModified = true; - } -} - -void NzNoiseMachine::SetHurstParameter(float h) -{ - if(h != m_hurst) - { - m_hurst = h; - m_parametersModified = true; - } -} - -void NzNoiseMachine::SetOctavesNumber(float octaves) -{ - if(octaves != m_octaves && octaves < 30) - { - m_octaves = octaves; - m_parametersModified = true; - } -} - -void NzNoiseMachine::RecomputeExponentArray() -{ - if(m_parametersModified) - { - float frequency = 1.0; - m_sum = 0.f; - for (int i(0) ; i < m_octaves; ++i) - { - exponent_array[i] = pow( frequency, -m_hurst ); - frequency *= m_lacunarity; - - m_sum += exponent_array[i]; - - } - m_parametersModified = false; - } -} - //------------------------------ FBM ------------------------------ float NzNoiseMachine::Get2DFBMNoiseValue(float x, float y, float res)