Noise: First pass of refactoring

Former-commit-id: 77de49ee01fea466cb97b22771e4c625389fd95c [formerly edce9427bc009c8ea6a6df35d9ce134a83ab985c]
Former-commit-id: 76227519c8be75a45f6f65250a0870c2eb866953
This commit is contained in:
Jérôme Leclercq
2016-06-18 12:36:20 +02:00
parent 81245a9c43
commit 5970682035
14 changed files with 485 additions and 535 deletions

View File

@@ -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<float, 4> 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<float> 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<float> coordinates, float scale) const
float Worley::Get(float x, float y, float scale) const
{
std::map<float, Vector2f> featurePoints;
std::map<float, Vector2f>::iterator it;
float xc, yc;
int x0, y0;
float fractx, fracty;
std::initializer_list<float>::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<float> 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<float> 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<float, Vector2f> & featurePoints) const
void Worley::SquareTest(int xi, int yi, float x, float y, std::map<float, Vector2f>& 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);