From 57d9af6b568a952e05e2b0171239bc0246cefdf3 Mon Sep 17 00:00:00 2001 From: Remi Beges Date: Tue, 29 May 2012 20:28:31 +0200 Subject: [PATCH] NzNoise new architecture + Perlin 1D algorithm modified --- include/Nazara/Noise/NoiseBase.hpp | 30 ++++++++ include/Nazara/Noise/NoiseMachine.hpp | 22 ++---- include/Nazara/Noise/Perlin1D.hpp | 38 ++++++++++ include/Nazara/Noise/Perlin1D.inl | 37 +++++++++ src/Nazara/Noise/NoiseBase.cpp | 60 +++++++++++++++ src/Nazara/Noise/NoiseMachine.cpp | 103 ++++++++------------------ 6 files changed, 203 insertions(+), 87 deletions(-) create mode 100644 include/Nazara/Noise/NoiseBase.hpp create mode 100644 include/Nazara/Noise/Perlin1D.hpp create mode 100644 include/Nazara/Noise/Perlin1D.inl create mode 100644 src/Nazara/Noise/NoiseBase.cpp diff --git a/include/Nazara/Noise/NoiseBase.hpp b/include/Nazara/Noise/NoiseBase.hpp new file mode 100644 index 000000000..af8a66632 --- /dev/null +++ b/include/Nazara/Noise/NoiseBase.hpp @@ -0,0 +1,30 @@ +// 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 NOISEBASE_H +#define NOISEBASE_H + +#include + +class NzNoiseBase +{ + public: + NzNoiseBase(int seed = 0); + virtual ~NzNoiseBase(); + + void SetNewSeed(int seed); + int GetUniformRandomValue(); + void ShufflePermutationTable(); + protected: + int perm[512]; + private: + int Ua, Uc, Um; + int UcurrentSeed; + int Uprevious, Ulast; + +}; + +#endif // NOISEBASE_H diff --git a/include/Nazara/Noise/NoiseMachine.hpp b/include/Nazara/Noise/NoiseMachine.hpp index 5f8787ad4..fa3a60ea1 100644 --- a/include/Nazara/Noise/NoiseMachine.hpp +++ b/include/Nazara/Noise/NoiseMachine.hpp @@ -8,22 +8,22 @@ #define NOISEMACHINE_HPP #include +//#include +#include "NoiseBase.hpp" #include #include #include -//TODO : tableau de gradients en float au lieu de int ? Ou alors condition ternaires ? +//TODO : tableau de gradients en float au lieu de int ? Ou condition ternaires ? +// utiliser fastfloor partout +// vérifier bon fonctionnement perlin1d -class NzNoiseMachine +class NzNoiseMachine : public NzNoiseBase { public: NzNoiseMachine(int seed = 0); ~NzNoiseMachine(); - void SetNewSeed(int seed); - int GetUniformRandomValue(); - void ShufflePermutationTable(); - float Get1DPerlinNoiseValue (float x, float res); float Get2DPerlinNoiseValue (float x, float y, float res); float Get3DPerlinNoiseValue (float x, float y, float z, float res); @@ -55,20 +55,12 @@ class NzNoiseMachine //Pour tronquer les nombres int fastfloor(float n); - float pi; - int perm[512]; - int PermutationTemp[256]; + int gradient1[2]; float gradient2[8][2]; int gradient3[16][3]; int gradient4[32][4]; int lookupTable4D[64][4]; - //multiplicative congruential generator - int UcurrentSeed; - int Ua,Uc,Um; - int Uprevious; - int Ulast; - //----------------------- Simplex variables -------------------------------------- float n1, n2, n3, n4, n5; diff --git a/include/Nazara/Noise/Perlin1D.hpp b/include/Nazara/Noise/Perlin1D.hpp new file mode 100644 index 000000000..533ccc0a7 --- /dev/null +++ b/include/Nazara/Noise/Perlin1D.hpp @@ -0,0 +1,38 @@ +// 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 PERLIN1D_H +#define PERLIN1D_H + +#include +//#include +#include "NoiseBase.hpp" + +template class NzPerlin1D : public NzNoiseBase +{ + public: + NzPerlin1D(); + T GetValue(T x, T res); + ~NzPerlin1D() = default; + protected: + private: + int x0; + int gi0,gi1; + int ii; + int gradient1[16]; + T s,t; + T Cx; + T nx; + T tmp; +}; + +typedef NzPerlin1D NzPerlin1Df; +typedef NzPerlin1D NzPerlin1Dd; + +//#include +#include "Perlin1D.inl" + +#endif // PERLIN1D_H diff --git a/include/Nazara/Noise/Perlin1D.inl b/include/Nazara/Noise/Perlin1D.inl new file mode 100644 index 000000000..75b5c524e --- /dev/null +++ b/include/Nazara/Noise/Perlin1D.inl @@ -0,0 +1,37 @@ +// 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 + +template +NzPerlin1D::NzPerlin1D() +{ + gradient1[0] = 1; + gradient1[1] = -1; +} + +template +T NzPerlin1D::GetValue(T x, T res) +{ + nx = x/res; + x0 = static_cast(nx); + ii = x0 & 255; + + gi0 = perm[ii] % 2; + gi1 = perm[ii + 1] % 2; + + tmp = nx-x0; + s = gradient1[gi0]*tmp; + + tmp = nx-(x0+1); + t = gradient1[gi1]*tmp; + + tmp = nx-x0; + Cx = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); + + return s + Cx*(t-s); +} diff --git a/src/Nazara/Noise/NoiseBase.cpp b/src/Nazara/Noise/NoiseBase.cpp new file mode 100644 index 000000000..940a3ecf8 --- /dev/null +++ b/src/Nazara/Noise/NoiseBase.cpp @@ -0,0 +1,60 @@ +// 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 "NoiseBase.hpp" +//#include +//#include +//#include +//#include + +NzNoiseBase::NzNoiseBase(int seed) +{ + Ua = 16807; + Uc = 0; + Um = 2147483647; + UcurrentSeed = 0; + Uprevious = 0; + + SetNewSeed(seed); + + for(int i(0) ; i < 256 ; i++) + perm[i] = i; + +} + +void NzNoiseBase::SetNewSeed(int seed) +{ + Uprevious = seed; + UcurrentSeed = seed; +} + +int NzNoiseBase::GetUniformRandomValue() +{ + Ulast = Ua*Uprevious + Uc%Um; + Uprevious = Ulast; + return Ulast; +} + +void NzNoiseBase::ShufflePermutationTable() +{ + int xchanger; + unsigned int ncase; + + for(int j(0) ; j < 10 ; ++j) + for (int i(0); i < 256 ; ++i) + { + ncase = this->GetUniformRandomValue() & 255; + xchanger = perm[i]; + perm[i] = perm[ncase]; + perm[ncase] = xchanger; + } + + for(int i(256) ; i < 512; ++i) + perm[i] = perm[i & 255]; +} + +NzNoiseBase::~NzNoiseBase() +{ + //dtor +} diff --git a/src/Nazara/Noise/NoiseMachine.cpp b/src/Nazara/Noise/NoiseMachine.cpp index 28e7fa82a..8a1e2e697 100644 --- a/src/Nazara/Noise/NoiseMachine.cpp +++ b/src/Nazara/Noise/NoiseMachine.cpp @@ -1,18 +1,14 @@ // 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 +#include "NoiseMachine.hpp" +//#include +//#include +//#include +//#include NzNoiseMachine::NzNoiseMachine(int seed) { - pi = 3.14159265; - SkewCoeff2D = 0.5*(sqrt(3.0) - 1.0); UnskewCoeff2D = (3.0-sqrt(3.0))/6; @@ -22,16 +18,6 @@ NzNoiseMachine::NzNoiseMachine(int seed) SkewCoeff4D = (sqrt(5) - 1)/4; UnskewCoeff4D = (5 - sqrt(5))/20; - Ua = 16807; - Uc = 0; - Um = 2147483647; - UcurrentSeed = 0; - Uprevious = 0; - - SetNewSeed(seed); - - for(int i(0) ; i < 256 ; i++) - PermutationTemp[i] = i; int lookupTemp4D[][4] = { @@ -49,6 +35,9 @@ NzNoiseMachine::NzNoiseMachine(int seed) for(int j(0) ; j < 4 ; ++j) lookupTable4D[i][j] = lookupTemp4D[i][j]; + gradient1[0] = 1; + gradient1[1] = -1; + float unit = 1.0/sqrt(2); float grad2Temp[][2] = {{unit,unit},{-unit,unit},{unit,-unit},{-unit,-unit}, {1,0},{-1,0},{0,1},{0,-1}}; @@ -94,56 +83,26 @@ NzNoiseMachine::~NzNoiseMachine() { } -void NzNoiseMachine::SetNewSeed(int seed) -{ - Uprevious = seed; - UcurrentSeed = seed; -} -int NzNoiseMachine::GetUniformRandomValue() -{ - Ulast = Ua*Uprevious + Uc%Um; - Uprevious = Ulast; - return Ulast; -} - -void NzNoiseMachine::ShufflePermutationTable() -{ - int xchanger; - unsigned int ncase; - - for(int j(0) ; j < 10 ; ++j) - for (int i(0); i < 256 ; ++i) - { - ncase = this->GetUniformRandomValue() & 255; - xchanger = PermutationTemp[i]; - PermutationTemp[i] = PermutationTemp[ncase]; - PermutationTemp[ncase] = xchanger; - } - - for(int i(0) ; i < 512; ++i) - perm[i]=PermutationTemp[i & 255]; -} //------------------------------ PERLIN ------------------------------ float NzNoiseMachine::Get1DPerlinNoiseValue(float x, float res) { nx = x/res; - x0 = (int)(nx); + x0 = static_cast(nx); ii = x0 & 255; - gi0 = perm[ii] % 16; - gi1 = perm[ii + 1] % 16; + gi0 = perm[ii] % 2; + gi1 = perm[ii + 1] % 2; temp.x = nx-x0; - temp.y = ny-y0; - s[0] = gradient3[gi0][0]*temp.x; + s[0] = gradient1[gi0]*temp.x; temp.x = nx-(x0+1); - t[0] = gradient3[gi1][0]*temp.x; + t[0] = gradient1[gi1]*temp.x; tmp = nx-x0; Cx = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); @@ -156,8 +115,8 @@ float NzNoiseMachine::Get2DPerlinNoiseValue(float x, float y, float res) nx = x/res; ny = y/res; - x0 = (int)(nx); - y0 = (int)(ny); + x0 = static_cast(nx); + y0 = static_cast(ny); ii = x0 & 255; jj = y0 & 255; @@ -200,9 +159,9 @@ float NzNoiseMachine::Get3DPerlinNoiseValue(float x, float y, float z, float res ny = y/res; nz = z/res; - x0 = (int)(nx); - y0 = (int)(ny); - z0 = (int)(nz); + x0 = static_cast(nx); + y0 = static_cast(ny); + z0 = static_cast(nz); ii = x0 & 255; jj = y0 & 255; @@ -279,10 +238,10 @@ float NzNoiseMachine::Get4DPerlinNoiseValue(float x, float y, float z, float w, nz = z/res; nw = w/res; - x0 = (int)(nx); - y0 = (int)(ny); - z0 = (int)(nz); - w0 = (int)(nw); + x0 = static_cast(nx); + y0 = static_cast(ny); + z0 = static_cast(nz); + w0 = static_cast(nw); ii = x0 & 255; jj = y0 & 255; @@ -749,9 +708,9 @@ float NzNoiseMachine::Get3DCellNoiseValue(float x, float y, float z, float res) y /= res; z /= res; - x0 = (int)(x); - y0 = (int)(y); - z0 = (int)(z); + x0 = static_cast(x); + y0 = static_cast(y); + z0 = static_cast(z); return 0; } @@ -762,10 +721,10 @@ float NzNoiseMachine::Get4DCellNoiseValue(float x, float y, float z, float w, fl z /= res; w /= res; - x0 = (int)(x) & 255; - y0 = (int)(y) & 255; - z0 = (int)(z) & 255; - w0 = (int)(w) & 255; + x0 = static_cast(x) & 255; + y0 = static_cast(y) & 255; + z0 = static_cast(z) & 255; + w0 = static_cast(w) & 255; return 0; } @@ -953,7 +912,7 @@ float NzNoiseMachine::Get3DHybridMultiFractalNoiseValue(float x, float y, float int NzNoiseMachine::fastfloor(float n) { if(n >= 0) - return int(n); + return static_cast(n); else - return int(n-1); + return static_cast(n-1); }