NzNoise new architecture + Perlin 1D algorithm modified

This commit is contained in:
Remi Beges 2012-05-29 20:28:31 +02:00
parent 7578a1b957
commit 57d9af6b56
6 changed files with 203 additions and 87 deletions

View File

@ -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 <Nazara/Prerequesites.hpp>
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

View File

@ -8,22 +8,22 @@
#define NOISEMACHINE_HPP #define NOISEMACHINE_HPP
#include <Nazara/Prerequesites.hpp> #include <Nazara/Prerequesites.hpp>
//#include <Nazara/Noise/NoiseBase.hpp>
#include "NoiseBase.hpp"
#include <Nazara/Math/Vector2.hpp> #include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp> #include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp> #include <Nazara/Math/Vector4.hpp>
//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: public:
NzNoiseMachine(int seed = 0); NzNoiseMachine(int seed = 0);
~NzNoiseMachine(); ~NzNoiseMachine();
void SetNewSeed(int seed);
int GetUniformRandomValue();
void ShufflePermutationTable();
float Get1DPerlinNoiseValue (float x, float res); float Get1DPerlinNoiseValue (float x, float res);
float Get2DPerlinNoiseValue (float x, float y, float res); float Get2DPerlinNoiseValue (float x, float y, float res);
float Get3DPerlinNoiseValue (float x, float y, float z, float res); float Get3DPerlinNoiseValue (float x, float y, float z, float res);
@ -55,20 +55,12 @@ class NzNoiseMachine
//Pour tronquer les nombres //Pour tronquer les nombres
int fastfloor(float n); int fastfloor(float n);
float pi; int gradient1[2];
int perm[512];
int PermutationTemp[256];
float gradient2[8][2]; float gradient2[8][2];
int gradient3[16][3]; int gradient3[16][3];
int gradient4[32][4]; int gradient4[32][4];
int lookupTable4D[64][4]; int lookupTable4D[64][4];
//multiplicative congruential generator
int UcurrentSeed;
int Ua,Uc,Um;
int Uprevious;
int Ulast;
//----------------------- Simplex variables -------------------------------------- //----------------------- Simplex variables --------------------------------------
float n1, n2, n3, n4, n5; float n1, n2, n3, n4, n5;

View File

@ -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 <Nazara/Prerequesites.hpp>
//#include <Nazara/Noise/NoiseBase.hpp>
#include "NoiseBase.hpp"
template <typename T> 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<float> NzPerlin1Df;
typedef NzPerlin1D<double> NzPerlin1Dd;
//#include <Nazara/Noise/Perlin1D.inl>
#include "Perlin1D.inl"
#endif // PERLIN1D_H

View File

@ -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 <Nazara/Noise/Error.hpp>
//#include <Nazara/Noise/Config.hpp>
//#include <Nazara/Noise/Debug.hpp>
#include <iostream>
template <typename T>
NzPerlin1D<T>::NzPerlin1D()
{
gradient1[0] = 1;
gradient1[1] = -1;
}
template <typename T>
T NzPerlin1D<T>::GetValue(T x, T res)
{
nx = x/res;
x0 = static_cast<int>(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);
}

View File

@ -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 <Nazara/Noise/NoiseBase.hpp>
//#include <Nazara/Noise/Error.hpp>
//#include <Nazara/Noise/Config.hpp>
//#include <Nazara/Noise/Debug.hpp>
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
}

View File

@ -1,18 +1,14 @@
// Copyright (C) 2012 Rémi Bèges // Copyright (C) 2012 Rémi Bèges
// This file is part of the "Nazara Engine". // This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include "NoiseMachine.hpp"
#include <Nazara/Noise/NoiseMachine.hpp> //#include <Nazara/Noise/NoiseMachine.hpp>
#include <cmath> //#include <Nazara/Noise/Error.hpp>
//#include <Nazara/Noise/Config.hpp>
#include <Nazara/Core/Error.hpp> //#include <Nazara/Noise/Debug.hpp>
#include <Nazara/Noise/Config.hpp>
#include <Nazara/Noise/Debug.hpp>
NzNoiseMachine::NzNoiseMachine(int seed) NzNoiseMachine::NzNoiseMachine(int seed)
{ {
pi = 3.14159265;
SkewCoeff2D = 0.5*(sqrt(3.0) - 1.0); SkewCoeff2D = 0.5*(sqrt(3.0) - 1.0);
UnskewCoeff2D = (3.0-sqrt(3.0))/6; UnskewCoeff2D = (3.0-sqrt(3.0))/6;
@ -22,16 +18,6 @@ NzNoiseMachine::NzNoiseMachine(int seed)
SkewCoeff4D = (sqrt(5) - 1)/4; SkewCoeff4D = (sqrt(5) - 1)/4;
UnskewCoeff4D = (5 - sqrt(5))/20; 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] = int lookupTemp4D[][4] =
{ {
@ -49,6 +35,9 @@ NzNoiseMachine::NzNoiseMachine(int seed)
for(int j(0) ; j < 4 ; ++j) for(int j(0) ; j < 4 ; ++j)
lookupTable4D[i][j] = lookupTemp4D[i][j]; lookupTable4D[i][j] = lookupTemp4D[i][j];
gradient1[0] = 1;
gradient1[1] = -1;
float unit = 1.0/sqrt(2); float unit = 1.0/sqrt(2);
float grad2Temp[][2] = {{unit,unit},{-unit,unit},{unit,-unit},{-unit,-unit}, float grad2Temp[][2] = {{unit,unit},{-unit,unit},{unit,-unit},{-unit,-unit},
{1,0},{-1,0},{0,1},{0,-1}}; {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 ------------------------------ //------------------------------ PERLIN ------------------------------
float NzNoiseMachine::Get1DPerlinNoiseValue(float x, float res) float NzNoiseMachine::Get1DPerlinNoiseValue(float x, float res)
{ {
nx = x/res; nx = x/res;
x0 = (int)(nx); x0 = static_cast<int>(nx);
ii = x0 & 255; ii = x0 & 255;
gi0 = perm[ii] % 16; gi0 = perm[ii] % 2;
gi1 = perm[ii + 1] % 16; gi1 = perm[ii + 1] % 2;
temp.x = nx-x0; 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); temp.x = nx-(x0+1);
t[0] = gradient3[gi1][0]*temp.x; t[0] = gradient1[gi1]*temp.x;
tmp = nx-x0; tmp = nx-x0;
Cx = tmp * tmp * tmp * (tmp * (tmp * 6 - 15) + 10); 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; nx = x/res;
ny = y/res; ny = y/res;
x0 = (int)(nx); x0 = static_cast<int>(nx);
y0 = (int)(ny); y0 = static_cast<int>(ny);
ii = x0 & 255; ii = x0 & 255;
jj = y0 & 255; jj = y0 & 255;
@ -200,9 +159,9 @@ float NzNoiseMachine::Get3DPerlinNoiseValue(float x, float y, float z, float res
ny = y/res; ny = y/res;
nz = z/res; nz = z/res;
x0 = (int)(nx); x0 = static_cast<int>(nx);
y0 = (int)(ny); y0 = static_cast<int>(ny);
z0 = (int)(nz); z0 = static_cast<int>(nz);
ii = x0 & 255; ii = x0 & 255;
jj = y0 & 255; jj = y0 & 255;
@ -279,10 +238,10 @@ float NzNoiseMachine::Get4DPerlinNoiseValue(float x, float y, float z, float w,
nz = z/res; nz = z/res;
nw = w/res; nw = w/res;
x0 = (int)(nx); x0 = static_cast<int>(nx);
y0 = (int)(ny); y0 = static_cast<int>(ny);
z0 = (int)(nz); z0 = static_cast<int>(nz);
w0 = (int)(nw); w0 = static_cast<int>(nw);
ii = x0 & 255; ii = x0 & 255;
jj = y0 & 255; jj = y0 & 255;
@ -749,9 +708,9 @@ float NzNoiseMachine::Get3DCellNoiseValue(float x, float y, float z, float res)
y /= res; y /= res;
z /= res; z /= res;
x0 = (int)(x); x0 = static_cast<int>(x);
y0 = (int)(y); y0 = static_cast<int>(y);
z0 = (int)(z); z0 = static_cast<int>(z);
return 0; return 0;
} }
@ -762,10 +721,10 @@ float NzNoiseMachine::Get4DCellNoiseValue(float x, float y, float z, float w, fl
z /= res; z /= res;
w /= res; w /= res;
x0 = (int)(x) & 255; x0 = static_cast<int>(x) & 255;
y0 = (int)(y) & 255; y0 = static_cast<int>(y) & 255;
z0 = (int)(z) & 255; z0 = static_cast<int>(z) & 255;
w0 = (int)(w) & 255; w0 = static_cast<int>(w) & 255;
return 0; return 0;
} }
@ -953,7 +912,7 @@ float NzNoiseMachine::Get3DHybridMultiFractalNoiseValue(float x, float y, float
int NzNoiseMachine::fastfloor(float n) int NzNoiseMachine::fastfloor(float n)
{ {
if(n >= 0) if(n >= 0)
return int(n); return static_cast<int>(n);
else else
return int(n-1); return static_cast<int>(n-1);
} }