Noise: First pass of refactoring
Former-commit-id: 77de49ee01fea466cb97b22771e4c625389fd95c [formerly edce9427bc009c8ea6a6df35d9ce134a83ab985c] Former-commit-id: 76227519c8be75a45f6f65250a0870c2eb866953
This commit is contained in:
parent
81245a9c43
commit
5970682035
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
// Copyright (C) 2015 Jérôme Leclercq
|
// Copyright (C) 2015 Jérôme Leclercq
|
||||||
// This file is part of the "Nazara Engine - Mathematics module"
|
// This file is part of the "Nazara Engine - Mathematics module"
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
@ -28,6 +29,10 @@
|
||||||
#define M_SQRT3 1.7320508075688772935274463
|
#define M_SQRT3 1.7320508075688772935274463
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef M_SQRT5
|
||||||
|
#define M_SQRT5 2.23606797749979
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
template<typename T> /*constexpr*/ T Approach(T value, T objective, T increment);
|
template<typename T> /*constexpr*/ T Approach(T value, T objective, T increment);
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,9 @@ namespace Nz
|
||||||
FBM(const FBM&) = delete;
|
FBM(const FBM&) = delete;
|
||||||
~FBM() = default;
|
~FBM() = default;
|
||||||
|
|
||||||
float Get(std::initializer_list<float> 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;
|
FBM& operator=(const FBM&) = delete;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,9 @@ namespace Nz
|
||||||
HybridMultiFractal(const HybridMultiFractal&) = delete;
|
HybridMultiFractal(const HybridMultiFractal&) = delete;
|
||||||
~HybridMultiFractal() = default;
|
~HybridMultiFractal() = default;
|
||||||
|
|
||||||
float Get(std::initializer_list<float> 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;
|
HybridMultiFractal& operator=(const HybridMultiFractal&) = delete;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,10 @@ namespace Nz
|
||||||
MixerBase();
|
MixerBase();
|
||||||
~MixerBase() = default;
|
~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 GetHurstParameter() const;
|
||||||
float GetLacunarity() const;
|
float GetLacunarity() const;
|
||||||
float GetOctaveNumber() const;
|
float GetOctaveNumber() const;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,11 @@
|
||||||
#define NAZARA_NOISEBASE_HPP
|
#define NAZARA_NOISEBASE_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Math/Vector2.hpp>
|
||||||
|
#include <Nazara/Math/Vector3.hpp>
|
||||||
|
#include <Nazara/Math/Vector4.hpp>
|
||||||
#include <Nazara/Noise/Config.hpp>
|
#include <Nazara/Noise/Config.hpp>
|
||||||
|
#include <array>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -17,21 +21,26 @@ namespace Nz
|
||||||
NoiseBase(unsigned int seed = 0);
|
NoiseBase(unsigned int seed = 0);
|
||||||
~NoiseBase() = default;
|
~NoiseBase() = default;
|
||||||
|
|
||||||
virtual float Get(std::initializer_list<float> 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();
|
float GetScale();
|
||||||
|
|
||||||
void SetScale(float scale);
|
void SetScale(float scale);
|
||||||
void SetSeed(unsigned int seed);
|
void SetSeed(unsigned int seed);
|
||||||
|
|
||||||
void Shuffle();
|
void Shuffle();
|
||||||
void Shuffle(unsigned int amount);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
unsigned int perm[512];
|
std::array<std::size_t, 3 * 256> m_permutations;
|
||||||
float m_scale;
|
float m_scale;
|
||||||
|
|
||||||
|
static std::array<Vector2f, 2 * 2 * 2> s_gradients2;
|
||||||
|
static std::array<Vector3f, 2 * 2 * 2 * 2> s_gradients3;
|
||||||
|
static std::array<Vector4f, 2 * 2 * 2 * 2 * 2> s_gradients4;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::default_random_engine generator;
|
std::default_random_engine m_randomEngine;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,21 +15,13 @@ namespace Nz
|
||||||
class NAZARA_NOISE_API Perlin : public NoiseBase
|
class NAZARA_NOISE_API Perlin : public NoiseBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Perlin();
|
Perlin() = default;
|
||||||
Perlin(unsigned int seed);
|
Perlin(unsigned int seed);
|
||||||
~Perlin() = default;
|
~Perlin() = default;
|
||||||
|
|
||||||
float Get(std::initializer_list<float> 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;
|
||||||
protected:
|
float Get(float x, float y, float z, float w, float scale) const override;
|
||||||
float _2D(std::initializer_list<float> coordinates, float scale) const;
|
|
||||||
float _3D(std::initializer_list<float> coordinates, float scale) const;
|
|
||||||
float _4D(std::initializer_list<float> coordinates, float scale) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const float gradient2[8][2];
|
|
||||||
const float gradient3[16][3];
|
|
||||||
const float gradient4[32][4];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,28 +15,13 @@ namespace Nz
|
||||||
class NAZARA_NOISE_API Simplex : public NoiseBase
|
class NAZARA_NOISE_API Simplex : public NoiseBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Simplex();
|
Simplex() = default;
|
||||||
Simplex(unsigned int seed);
|
Simplex(unsigned int seed);
|
||||||
~Simplex() = default;
|
~Simplex() = default;
|
||||||
|
|
||||||
float Get(std::initializer_list<float> 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;
|
||||||
protected:
|
float Get(float x, float y, float z, float w, float scale) const override;
|
||||||
float _2D(std::initializer_list<float> coordinates, float scale) const;
|
|
||||||
float _3D(std::initializer_list<float> coordinates, float scale) const;
|
|
||||||
float _4D(std::initializer_list<float> 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];
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,23 +18,20 @@ namespace Nz
|
||||||
class NAZARA_NOISE_API Worley : public NoiseBase
|
class NAZARA_NOISE_API Worley : public NoiseBase
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Worley();
|
Worley();
|
||||||
Worley(unsigned int seed);
|
Worley(unsigned int seed);
|
||||||
~Worley() = default;
|
~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<float> coordinates, float scale) const;
|
void Set(WorleyFunction func);
|
||||||
|
|
||||||
protected:
|
|
||||||
float _2D(std::initializer_list<float> coordinates, float scale) const;
|
|
||||||
float _3D(std::initializer_list<float> coordinates, float scale) const;
|
|
||||||
float _4D(std::initializer_list<float> coordinates, float scale) const;
|
|
||||||
void _SquareTest(int xi, int yi, float x, float y, std::map<float, Vector2f> & featurePoints) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const float scales[4];
|
void SquareTest(int xi, int yi, float x, float y, std::map<float, Vector2f> & featurePoints) const;
|
||||||
WorleyFunction function;
|
|
||||||
|
WorleyFunction m_function;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,20 +11,51 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
float FBM::Get(std::initializer_list<float> coordinates, float scale) const
|
///TODO: Handle with variadic templates
|
||||||
|
float FBM::Get(float x, float y, float scale) const
|
||||||
{
|
{
|
||||||
float value = 0.0;
|
float value = 0.f;
|
||||||
|
for(int i = 0; i < m_octaves; ++i)
|
||||||
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;
|
scale *= m_lacunarity;
|
||||||
}
|
}
|
||||||
|
|
||||||
float remainder = m_octaves - static_cast<int>(m_octaves);
|
float remainder = m_octaves - static_cast<int>(m_octaves);
|
||||||
|
|
||||||
if(std::fabs(remainder) > 0.01f)
|
if(std::fabs(remainder) > 0.01f)
|
||||||
value += remainder * m_source.Get(coordinates,scale) * m_exponent_array.at(static_cast<int>(m_octaves-1));
|
value += remainder * m_source.Get(x, y, scale) * m_exponent_array.at(static_cast<int>(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<int>(m_octaves);
|
||||||
|
if(std::fabs(remainder) > 0.01f)
|
||||||
|
value += remainder * m_source.Get(x, y, z, scale) * m_exponent_array.at(static_cast<int>(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<int>(m_octaves);
|
||||||
|
if(std::fabs(remainder) > 0.01f)
|
||||||
|
value += remainder * m_source.Get(x, y, z, w, scale) * m_exponent_array.at(static_cast<int>(m_octaves-1));
|
||||||
|
|
||||||
return value / m_sum;
|
return value / m_sum;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
float HybridMultiFractal::Get(std::initializer_list<float> coordinates, float scale) const
|
float HybridMultiFractal::Get(float x, float y, float scale) const
|
||||||
{
|
{
|
||||||
float offset = 1.0f;
|
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 weight = value;
|
||||||
float signal = 0.f;
|
float signal = 0.f;
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ namespace Nz
|
||||||
if (weight > 1.f)
|
if (weight > 1.f)
|
||||||
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;
|
value += weight * signal;
|
||||||
weight *= signal;
|
weight *= signal;
|
||||||
scale *= m_lacunarity;
|
scale *= m_lacunarity;
|
||||||
|
|
@ -35,7 +35,63 @@ namespace Nz
|
||||||
float remainder = m_octaves - static_cast<int>(m_octaves);
|
float remainder = m_octaves - static_cast<int>(m_octaves);
|
||||||
|
|
||||||
if (remainder > 0.f)
|
if (remainder > 0.f)
|
||||||
value += remainder * m_source.Get(coordinates,scale) * m_exponent_array.at(static_cast<int>(m_octaves-1));
|
value += remainder * m_source.Get(x, y, scale) * m_exponent_array.at(static_cast<int>(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<int>(m_octaves);
|
||||||
|
|
||||||
|
if (remainder > 0.f)
|
||||||
|
value += remainder * m_source.Get(x, y, z, scale) * m_exponent_array.at(static_cast<int>(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<int>(m_octaves);
|
||||||
|
|
||||||
|
if (remainder > 0.f)
|
||||||
|
value += remainder * m_source.Get(x, y, z, w, scale) * m_exponent_array.at(static_cast<int>(m_octaves-1));
|
||||||
|
|
||||||
return value / m_sum - offset;
|
return value / m_sum - offset;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,13 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
NoiseBase::NoiseBase(unsigned int seed)
|
NoiseBase::NoiseBase(unsigned int seed) :
|
||||||
|
m_scale(0.05f)
|
||||||
{
|
{
|
||||||
SetSeed(seed);
|
SetSeed(seed);
|
||||||
m_scale = 0.05f;
|
|
||||||
|
|
||||||
for(unsigned int i(0) ; i < 512; ++i)
|
// Fill permutations with initial values
|
||||||
perm[i] = i & 255;
|
std::iota(m_permutations.begin(), m_permutations.begin() + 256, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
float NoiseBase::GetScale()
|
float NoiseBase::GetScale()
|
||||||
|
|
@ -28,32 +28,46 @@ namespace Nz
|
||||||
|
|
||||||
void NoiseBase::SetSeed(unsigned int seed)
|
void NoiseBase::SetSeed(unsigned int seed)
|
||||||
{
|
{
|
||||||
generator.seed(seed);
|
m_randomEngine.seed(seed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoiseBase::Shuffle()
|
void NoiseBase::Shuffle()
|
||||||
{
|
{
|
||||||
int xchanger;
|
std::shuffle(m_permutations.begin(), m_permutations.begin() + 256, m_randomEngine);
|
||||||
unsigned int ncase;
|
|
||||||
|
|
||||||
for(unsigned int i(0) ; i < 256 ; i++)
|
for(std::size_t i = 1; i < (m_permutations.size() / 256); ++i)
|
||||||
perm[i] = i;
|
std::copy(m_permutations.begin(), m_permutations.begin() + 256, m_permutations.begin() + 256 * 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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoiseBase::Shuffle(unsigned int amount)
|
std::array<Vector2f, 2 * 2 * 2> 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<Vector3f, 2 * 2 * 2 * 2> 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<Vector4f, 2 * 2 * 2 * 2 * 2> 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}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,68 +10,27 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
Perlin::Perlin() :
|
Perlin::Perlin(unsigned int seed) :
|
||||||
gradient2{
|
Perlin()
|
||||||
{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()
|
|
||||||
{
|
{
|
||||||
SetSeed(seed);
|
SetSeed(seed);
|
||||||
Shuffle();
|
Shuffle();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Perlin::Get(std::initializer_list<float> coordinates, float scale) const
|
float Perlin::Get(float x, float y, float scale) const
|
||||||
{
|
{
|
||||||
switch(coordinates.size())
|
float xc, yc;
|
||||||
{
|
int x0, y0;
|
||||||
case 2:
|
int gi0,gi1,gi2,gi3;
|
||||||
return this->_2D(coordinates,scale);
|
int ii, jj;
|
||||||
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 Perlin::_2D(std::initializer_list<float> coordinates, float scale) const
|
float s,t,u,v;
|
||||||
{
|
float Cx,Cy;
|
||||||
thread_local float xc, yc;
|
float Li1, Li2;
|
||||||
thread_local int x0, y0;
|
float tempx,tempy;
|
||||||
thread_local int gi0,gi1,gi2,gi3;
|
|
||||||
thread_local int ii, jj;
|
|
||||||
|
|
||||||
thread_local float s,t,u,v;
|
xc = x * scale;
|
||||||
thread_local float Cx,Cy;
|
yc = y * scale;
|
||||||
thread_local float Li1, Li2;
|
|
||||||
thread_local float tempx,tempy;
|
|
||||||
|
|
||||||
std::initializer_list<float>::const_iterator it = coordinates.begin();
|
|
||||||
|
|
||||||
xc = *(it ) * scale;
|
|
||||||
yc = *(++it) * scale;
|
|
||||||
|
|
||||||
x0 = fastfloor(xc);
|
x0 = fastfloor(xc);
|
||||||
y0 = fastfloor(yc);
|
y0 = fastfloor(yc);
|
||||||
|
|
@ -79,10 +38,10 @@ namespace Nz
|
||||||
ii = x0 & 255;
|
ii = x0 & 255;
|
||||||
jj = y0 & 255;
|
jj = y0 & 255;
|
||||||
|
|
||||||
gi0 = perm[ii + perm[jj]] & 7;
|
gi0 = m_permutations[ii + m_permutations[jj]] & 7;
|
||||||
gi1 = perm[ii + 1 + perm[jj]] & 7;
|
gi1 = m_permutations[ii + 1 + m_permutations[jj]] & 7;
|
||||||
gi2 = perm[ii + perm[jj + 1]] & 7;
|
gi2 = m_permutations[ii + m_permutations[jj + 1]] & 7;
|
||||||
gi3 = perm[ii + 1 + perm[jj + 1]] & 7;
|
gi3 = m_permutations[ii + 1 + m_permutations[jj + 1]] & 7;
|
||||||
|
|
||||||
tempx = xc - x0;
|
tempx = xc - x0;
|
||||||
tempy = yc - y0;
|
tempy = yc - y0;
|
||||||
|
|
@ -90,16 +49,16 @@ namespace Nz
|
||||||
Cx = tempx * tempx * tempx * (tempx * (tempx * 6 - 15) + 10);
|
Cx = tempx * tempx * tempx * (tempx * (tempx * 6 - 15) + 10);
|
||||||
Cy = tempy * tempy * tempy * (tempy * (tempy * 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);
|
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);
|
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;
|
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);
|
Li1 = s + Cx*(t-s);
|
||||||
Li2 = u + Cx*(v-u);
|
Li2 = u + Cx*(v-u);
|
||||||
|
|
@ -107,26 +66,24 @@ namespace Nz
|
||||||
return Li1 + Cy*(Li2-Li1);
|
return Li1 + Cy*(Li2-Li1);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Perlin::_3D(std::initializer_list<float> coordinates, float scale) const
|
float Perlin::Get(float x, float y, float z, float scale) const
|
||||||
{
|
{
|
||||||
thread_local float xc, yc, zc;
|
float xc, yc, zc;
|
||||||
thread_local int x0, y0, z0;
|
int x0, y0, z0;
|
||||||
thread_local int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7;
|
int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7;
|
||||||
thread_local int ii, jj, kk;
|
int ii, jj, kk;
|
||||||
|
|
||||||
thread_local float Li1,Li2,Li3,Li4,Li5,Li6;
|
float Li1,Li2,Li3,Li4,Li5,Li6;
|
||||||
thread_local float s[2],t[2],u[2],v[2];
|
float s[2],t[2],u[2],v[2];
|
||||||
thread_local float Cx,Cy,Cz;
|
float Cx,Cy,Cz;
|
||||||
thread_local float nx,ny,nz;
|
float nx,ny,nz;
|
||||||
|
|
||||||
thread_local float tmp;
|
float tmp;
|
||||||
thread_local float tempx,tempy,tempz;
|
float tempx,tempy,tempz;
|
||||||
|
|
||||||
std::initializer_list<float>::const_iterator it = coordinates.begin();
|
xc = x * scale;
|
||||||
|
yc = y * scale;
|
||||||
xc = *(it ) * scale;
|
zc = z * scale;
|
||||||
yc = *(++it) * scale;
|
|
||||||
zc = *(++it) * scale;
|
|
||||||
|
|
||||||
x0 = fastfloor(xc);
|
x0 = fastfloor(xc);
|
||||||
y0 = fastfloor(yc);
|
y0 = fastfloor(yc);
|
||||||
|
|
@ -136,15 +93,15 @@ namespace Nz
|
||||||
jj = y0 & 255;
|
jj = y0 & 255;
|
||||||
kk = z0 & 255;
|
kk = z0 & 255;
|
||||||
|
|
||||||
gi0 = perm[ii + perm[jj + perm[kk]]] & 15;
|
gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk]]] & 15;
|
||||||
gi1 = perm[ii + 1 + perm[jj + perm[kk]]] & 15;
|
gi1 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk]]] & 15;
|
||||||
gi2 = perm[ii + perm[jj + 1 + perm[kk]]] & 15;
|
gi2 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk]]] & 15;
|
||||||
gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk]]] & 15;
|
gi3 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk]]] & 15;
|
||||||
|
|
||||||
gi4 = perm[ii + perm[jj + perm[kk + 1]]] & 15;
|
gi4 = m_permutations[ii + m_permutations[jj + m_permutations[kk + 1]]] & 15;
|
||||||
gi5 = perm[ii + 1 + perm[jj + perm[kk + 1]]] & 15;
|
gi5 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + 1]]] & 15;
|
||||||
gi6 = perm[ii + perm[jj + 1 + perm[kk + 1]]] & 15;
|
gi6 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + 1]]] & 15;
|
||||||
gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] & 15;
|
gi7 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1]]] & 15;
|
||||||
|
|
||||||
tempx = xc - x0;
|
tempx = xc - x0;
|
||||||
tempy = yc - y0;
|
tempy = yc - y0;
|
||||||
|
|
@ -154,29 +111,29 @@ namespace Nz
|
||||||
Cy = tempy * tempy * tempy * (tempy * (tempy * 6 - 15) + 10);
|
Cy = tempy * tempy * tempy * (tempy * (tempy * 6 - 15) + 10);
|
||||||
Cz = tempz * tempz * tempz * (tempz * (tempz * 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);
|
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);
|
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;
|
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;
|
tempy = yc - y0;
|
||||||
tempz = zc - (z0 + 1);
|
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);
|
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);
|
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;
|
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]);
|
Li1 = s[0] + Cx*(t[0]-s[0]);
|
||||||
Li2 = u[0] + Cx*(v[0]-u[0]);
|
Li2 = u[0] + Cx*(v[0]-u[0]);
|
||||||
|
|
@ -189,26 +146,24 @@ namespace Nz
|
||||||
return Li5 + Cz * (Li6-Li5);
|
return Li5 + Cz * (Li6-Li5);
|
||||||
}
|
}
|
||||||
|
|
||||||
float Perlin::_4D(std::initializer_list<float> 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;
|
float xc,yc,zc,wc;
|
||||||
thread_local int x0,y0,z0,w0;
|
int x0,y0,z0,w0;
|
||||||
thread_local int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15;
|
int gi0,gi1,gi2,gi3,gi4,gi5,gi6,gi7,gi8,gi9,gi10,gi11,gi12,gi13,gi14,gi15;
|
||||||
thread_local int ii,jj,kk,ll;
|
int ii,jj,kk,ll;
|
||||||
|
|
||||||
thread_local float Li1,Li2,Li3,Li4,Li5,Li6,Li7,Li8,Li9,Li10,Li11,Li12,Li13,Li14;
|
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];
|
float s[4],t[4],u[4],v[4];
|
||||||
thread_local float Cx,Cy,Cz,Cw;
|
float Cx,Cy,Cz,Cw;
|
||||||
|
|
||||||
thread_local float tmp;
|
float tmp;
|
||||||
thread_local float tempx,tempy,tempz,tempw;
|
float tempx,tempy,tempz,tempw;
|
||||||
|
|
||||||
std::initializer_list<float>::const_iterator it = coordinates.begin();
|
xc = x * scale;
|
||||||
|
yc = y * scale;
|
||||||
xc = *(it ) * scale;
|
zc = z * scale;
|
||||||
yc = *(++it) * scale;
|
wc = w * scale;
|
||||||
zc = *(++it) * scale;
|
|
||||||
wc = *(++it) * scale;
|
|
||||||
|
|
||||||
x0 = fastfloor(xc);
|
x0 = fastfloor(xc);
|
||||||
y0 = fastfloor(yc);
|
y0 = fastfloor(yc);
|
||||||
|
|
@ -220,25 +175,25 @@ namespace Nz
|
||||||
kk = z0 & 255;
|
kk = z0 & 255;
|
||||||
ll = w0 & 255;
|
ll = w0 & 255;
|
||||||
|
|
||||||
gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] & 31;
|
gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk + m_permutations[ll]]]] & 31;
|
||||||
gi1 = perm[ii + 1 + perm[jj + perm[kk + perm[ll]]]] & 31;
|
gi1 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + m_permutations[ll]]]] & 31;
|
||||||
gi2 = perm[ii + perm[jj + 1 + perm[kk + perm[ll]]]] & 31;
|
gi2 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll]]]] & 31;
|
||||||
gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[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;
|
gi4 = m_permutations[ii + m_permutations[jj + + m_permutations[kk + 1 + m_permutations[ll]]]] & 31;
|
||||||
gi5 = perm[ii + 1 + perm[jj + + perm[kk + 1 + perm[ll]]]] & 31;
|
gi5 = m_permutations[ii + 1 + m_permutations[jj + + m_permutations[kk + 1 + m_permutations[ll]]]] & 31;
|
||||||
gi6 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll]]]] & 31;
|
gi6 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll]]]] & 31;
|
||||||
gi7 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[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;
|
gi8 = m_permutations[ii + m_permutations[jj + m_permutations[kk + m_permutations[ll + 1]]]] & 31;
|
||||||
gi9 = perm[ii + 1 + perm[jj + perm[kk + perm[ll + 1]]]] & 31;
|
gi9 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + m_permutations[ll + 1]]]] & 31;
|
||||||
gi10 = perm[ii + perm[jj + 1 + perm[kk + perm[ll + 1]]]] & 31;
|
gi10 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + m_permutations[ll + 1]]]] & 31;
|
||||||
gi11 = perm[ii + 1 + perm[jj + 1 + perm[kk + perm[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;
|
gi12 = m_permutations[ii + m_permutations[jj + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31;
|
||||||
gi13 = perm[ii + 1 + perm[jj + perm[kk + 1 + perm[ll + 1]]]] & 31;
|
gi13 = m_permutations[ii + 1 + m_permutations[jj + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31;
|
||||||
gi14 = perm[ii + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31;
|
gi14 = m_permutations[ii + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31;
|
||||||
gi15 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] & 31;
|
gi15 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 + m_permutations[ll + 1]]]] & 31;
|
||||||
|
|
||||||
tempx = xc - x0;
|
tempx = xc - x0;
|
||||||
tempy = yc - y0;
|
tempy = yc - y0;
|
||||||
|
|
@ -250,58 +205,58 @@ namespace Nz
|
||||||
Cz = tempz * tempz * tempz * (tempz * (tempz * 6 - 15) + 10);
|
Cz = tempz * tempz * tempz * (tempz * (tempz * 6 - 15) + 10);
|
||||||
Cw = tempw * tempw * tempw * (tempw * (tempw * 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);
|
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);
|
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;
|
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;
|
tempy = yc - y0;
|
||||||
tempz = zc - (z0+1);
|
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);
|
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);
|
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;
|
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;
|
tempy = yc - y0;
|
||||||
tempz = zc - z0;
|
tempz = zc - z0;
|
||||||
tempw = wc - (w0+1);
|
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);
|
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);
|
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;
|
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;
|
tempy = yc - y0;
|
||||||
tempz = zc - (z0+1);
|
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);
|
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);
|
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;
|
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]);
|
Li1 = s[0] + Cx*(t[0]-s[0]);
|
||||||
Li2 = u[0] + Cx*(v[0]-u[0]);
|
Li2 = u[0] + Cx*(v[0]-u[0]);
|
||||||
|
|
|
||||||
|
|
@ -10,185 +10,95 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
Simplex::Simplex() :
|
namespace
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
|
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);
|
SetSeed(seed);
|
||||||
Shuffle();
|
Shuffle();
|
||||||
}
|
}
|
||||||
|
|
||||||
float Simplex::Get(std::initializer_list<float> 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<Vector2f, 3> 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<std::size_t, 3> gi =
|
||||||
{
|
{
|
||||||
case 2:
|
m_permutations[offset.x + m_permutations[offset.y]] & 7,
|
||||||
return this->_2D(coordinates,scale);
|
m_permutations[offset.x + off1.x + m_permutations[offset.y + off1.y]] & 7,
|
||||||
case 3:
|
m_permutations[offset.x + 1 + m_permutations[offset.y + 1]] & 7
|
||||||
return this->_3D(coordinates,scale);
|
};
|
||||||
case 4:
|
|
||||||
return this->_4D(coordinates,scale);
|
float n = 0.f;
|
||||||
default:
|
for (unsigned int i = 0; i < 3; ++i)
|
||||||
throw std::invalid_argument("Number of coordinates elements not comprised between 2 and 4");
|
{
|
||||||
|
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<float> coordinates, float scale) const
|
float Simplex::Get(float x, float y, float z, float scale) const
|
||||||
{
|
{
|
||||||
thread_local float xc,yc;
|
float xc, yc, zc;
|
||||||
thread_local int ii,jj;
|
int ii,jj,kk;
|
||||||
thread_local int gi0,gi1,gi2;
|
int gi0,gi1,gi2,gi3;
|
||||||
thread_local int skewedCubeOriginx,skewedCubeOriginy;
|
int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz;
|
||||||
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;
|
|
||||||
|
|
||||||
std::initializer_list<float>::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;
|
float sum;
|
||||||
yc = *(++it) * scale;
|
float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz;
|
||||||
|
float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz;
|
||||||
sum = (xc + yc) * SkewCoeff2D;
|
float d1x,d1y,d1z;
|
||||||
skewedCubeOriginx = fastfloor(xc + sum);
|
float d2x,d2y,d2z;
|
||||||
skewedCubeOriginy = fastfloor(yc + sum);
|
float d3x,d3y,d3z;
|
||||||
|
float d4x,d4y,d4z;
|
||||||
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<float> 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<float>::const_iterator it = coordinates.begin();
|
|
||||||
|
|
||||||
x = *(it );
|
|
||||||
y = *(++it);
|
|
||||||
z = *(++it);
|
|
||||||
|
|
||||||
xc = x * scale;
|
xc = x * scale;
|
||||||
yc = y * scale;
|
yc = y * scale;
|
||||||
zc = z * scale;
|
zc = z * scale;
|
||||||
|
|
||||||
sum = (xc + yc + zc) * SkewCoeff3D;
|
sum = (xc + yc + zc) * s_SkewCoeff3D;
|
||||||
skewedCubeOriginx = fastfloor(xc + sum);
|
skewedCubeOriginx = fastfloor(xc + sum);
|
||||||
skewedCubeOriginy = fastfloor(yc + sum);
|
skewedCubeOriginy = fastfloor(yc + sum);
|
||||||
skewedCubeOriginz = fastfloor(zc + sum);
|
skewedCubeOriginz = fastfloor(zc + sum);
|
||||||
|
|
||||||
sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz) * UnskewCoeff3D;
|
sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz) * s_UnskewCoeff3D;
|
||||||
unskewedCubeOriginx = skewedCubeOriginx - sum;
|
unskewedCubeOriginx = skewedCubeOriginx - sum;
|
||||||
unskewedCubeOriginy = skewedCubeOriginy - sum;
|
unskewedCubeOriginy = skewedCubeOriginy - sum;
|
||||||
unskewedCubeOriginz = skewedCubeOriginz - sum;
|
unskewedCubeOriginz = skewedCubeOriginz - sum;
|
||||||
|
|
@ -262,26 +172,26 @@ namespace Nz
|
||||||
d1y = unskewedDistToOriginy;
|
d1y = unskewedDistToOriginy;
|
||||||
d1z = unskewedDistToOriginz;
|
d1z = unskewedDistToOriginz;
|
||||||
|
|
||||||
d2x = d1x - off1x + UnskewCoeff3D;
|
d2x = d1x - off1x + s_UnskewCoeff3D;
|
||||||
d2y = d1y - off1y + UnskewCoeff3D;
|
d2y = d1y - off1y + s_UnskewCoeff3D;
|
||||||
d2z = d1z - off1z + UnskewCoeff3D;
|
d2z = d1z - off1z + s_UnskewCoeff3D;
|
||||||
|
|
||||||
d3x = d1x - off2x + 2.f*UnskewCoeff3D;
|
d3x = d1x - off2x + 2.f*s_UnskewCoeff3D;
|
||||||
d3y = d1y - off2y + 2.f*UnskewCoeff3D;
|
d3y = d1y - off2y + 2.f*s_UnskewCoeff3D;
|
||||||
d3z = d1z - off2z + 2.f*UnskewCoeff3D;
|
d3z = d1z - off2z + 2.f*s_UnskewCoeff3D;
|
||||||
|
|
||||||
d4x = d1x - 1.f + 3.f*UnskewCoeff3D;
|
d4x = d1x - 1.f + 3.f*s_UnskewCoeff3D;
|
||||||
d4y = d1y - 1.f + 3.f*UnskewCoeff3D;
|
d4y = d1y - 1.f + 3.f*s_UnskewCoeff3D;
|
||||||
d4z = d1z - 1.f + 3.f*UnskewCoeff3D;
|
d4z = d1z - 1.f + 3.f*s_UnskewCoeff3D;
|
||||||
|
|
||||||
ii = skewedCubeOriginx & 255;
|
ii = skewedCubeOriginx & 255;
|
||||||
jj = skewedCubeOriginy & 255;
|
jj = skewedCubeOriginy & 255;
|
||||||
kk = skewedCubeOriginz & 255;
|
kk = skewedCubeOriginz & 255;
|
||||||
|
|
||||||
gi0 = perm[ii + perm[jj + perm[kk ]]] % 12;
|
gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk ]]] % 12;
|
||||||
gi1 = perm[ii + off1x + perm[jj + off1y + perm[kk + off1z ]]] % 12;
|
gi1 = m_permutations[ii + off1x + m_permutations[jj + off1y + m_permutations[kk + off1z ]]] % 12;
|
||||||
gi2 = perm[ii + off2x + perm[jj + off2y + perm[kk + off2z ]]] % 12;
|
gi2 = m_permutations[ii + off2x + m_permutations[jj + off2y + m_permutations[kk + off2z ]]] % 12;
|
||||||
gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 ]]] % 12;
|
gi3 = m_permutations[ii + 1 + m_permutations[jj + 1 + m_permutations[kk + 1 ]]] % 12;
|
||||||
|
|
||||||
c1 = 0.6f - d1x * d1x - d1y * d1y - d1z * d1z;
|
c1 = 0.6f - d1x * d1x - d1y * d1y - d1z * d1z;
|
||||||
c2 = 0.6f - d2x * d2x - d2y * d2y - d2z * d2z;
|
c2 = 0.6f - d2x * d2x - d2y * d2y - d2z * d2z;
|
||||||
|
|
@ -291,69 +201,75 @@ namespace Nz
|
||||||
if(c1 < 0)
|
if(c1 < 0)
|
||||||
n1 = 0;
|
n1 = 0;
|
||||||
else
|
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)
|
if(c2 < 0)
|
||||||
n2 = 0;
|
n2 = 0;
|
||||||
else
|
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)
|
if(c3 < 0)
|
||||||
n3 = 0;
|
n3 = 0;
|
||||||
else
|
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)
|
if(c4 < 0)
|
||||||
n4 = 0;
|
n4 = 0;
|
||||||
else
|
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;
|
return (n1+n2+n3+n4)*32;
|
||||||
}
|
}
|
||||||
|
|
||||||
float Simplex::_4D(std::initializer_list<float> 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;
|
static std::array<Vector4ui, 64> lookupTable =
|
||||||
thread_local float x,y,z,w;
|
{
|
||||||
thread_local int ii,jj,kk,ll;
|
{
|
||||||
thread_local int gi0,gi1,gi2,gi3,gi4;
|
{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},
|
||||||
thread_local int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz,skewedCubeOriginw;
|
{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;
|
float xc,yc,zc,wc;
|
||||||
thread_local int off2x,off2y,off2z,off2w;
|
int ii,jj,kk,ll;
|
||||||
thread_local int off3x,off3y,off3z,off3w;
|
int gi0,gi1,gi2,gi3,gi4;
|
||||||
|
int skewedCubeOriginx,skewedCubeOriginy,skewedCubeOriginz,skewedCubeOriginw;
|
||||||
|
|
||||||
thread_local int c;
|
int off1x,off1y,off1z,off1w;
|
||||||
thread_local float n1,n2,n3,n4,n5;
|
int off2x,off2y,off2z,off2w;
|
||||||
thread_local float c1,c2,c3,c4,c5,c6;
|
int off3x,off3y,off3z,off3w;
|
||||||
|
|
||||||
thread_local float sum;
|
int c;
|
||||||
thread_local float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz,unskewedCubeOriginw;
|
float n1,n2,n3,n4,n5;
|
||||||
thread_local float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz,unskewedDistToOriginw;
|
float c1,c2,c3,c4,c5,c6;
|
||||||
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;
|
|
||||||
|
|
||||||
std::initializer_list<float>::const_iterator it = coordinates.begin();
|
float sum;
|
||||||
|
float unskewedCubeOriginx,unskewedCubeOriginy,unskewedCubeOriginz,unskewedCubeOriginw;
|
||||||
x = *(it );
|
float unskewedDistToOriginx,unskewedDistToOriginy,unskewedDistToOriginz,unskewedDistToOriginw;
|
||||||
y = *(++it);
|
float d1x,d2x,d3x,d4x,d5x;
|
||||||
z = *(++it);
|
float d1y,d2y,d3y,d4y,d5y;
|
||||||
w = *(++it);
|
float d1z,d2z,d3z,d4z,d5z;
|
||||||
|
float d1w,d2w,d3w,d4w,d5w;
|
||||||
|
|
||||||
xc = x * scale;
|
xc = x * scale;
|
||||||
yc = y * scale;
|
yc = y * scale;
|
||||||
zc = z * scale;
|
zc = z * scale;
|
||||||
wc = w * scale;
|
wc = w * scale;
|
||||||
|
|
||||||
sum = (xc + yc + zc + wc) * SkewCoeff4D;
|
sum = (xc + yc + zc + wc) * s_SkewCoeff4D;
|
||||||
skewedCubeOriginx = fastfloor(xc + sum);
|
skewedCubeOriginx = fastfloor(xc + sum);
|
||||||
skewedCubeOriginy = fastfloor(yc + sum);
|
skewedCubeOriginy = fastfloor(yc + sum);
|
||||||
skewedCubeOriginz = fastfloor(zc + sum);
|
skewedCubeOriginz = fastfloor(zc + sum);
|
||||||
skewedCubeOriginw = fastfloor(wc + sum);
|
skewedCubeOriginw = fastfloor(wc + sum);
|
||||||
|
|
||||||
sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz + skewedCubeOriginw) * UnskewCoeff4D;
|
sum = (skewedCubeOriginx + skewedCubeOriginy + skewedCubeOriginz + skewedCubeOriginw) * s_UnskewCoeff4D;
|
||||||
unskewedCubeOriginx = skewedCubeOriginx - sum;
|
unskewedCubeOriginx = skewedCubeOriginx - sum;
|
||||||
unskewedCubeOriginy = skewedCubeOriginy - sum;
|
unskewedCubeOriginy = skewedCubeOriginy - sum;
|
||||||
unskewedCubeOriginz = skewedCubeOriginz - sum;
|
unskewedCubeOriginz = skewedCubeOriginz - sum;
|
||||||
|
|
@ -372,56 +288,56 @@ namespace Nz
|
||||||
c6 = (unskewedDistToOriginz > unskewedDistToOriginw) ? 1 : 0;
|
c6 = (unskewedDistToOriginz > unskewedDistToOriginw) ? 1 : 0;
|
||||||
c = c1 + c2 + c3 + c4 + c5 + c6;
|
c = c1 + c2 + c3 + c4 + c5 + c6;
|
||||||
|
|
||||||
off1x = lookupTable4D[c][0] >= 3 ? 1 : 0;
|
off1x = lookupTable[c][0] >= 3 ? 1 : 0;
|
||||||
off1y = lookupTable4D[c][1] >= 3 ? 1 : 0;
|
off1y = lookupTable[c][1] >= 3 ? 1 : 0;
|
||||||
off1z = lookupTable4D[c][2] >= 3 ? 1 : 0;
|
off1z = lookupTable[c][2] >= 3 ? 1 : 0;
|
||||||
off1w = lookupTable4D[c][3] >= 3 ? 1 : 0;
|
off1w = lookupTable[c][3] >= 3 ? 1 : 0;
|
||||||
|
|
||||||
off2x = lookupTable4D[c][0] >= 2 ? 1 : 0;
|
off2x = lookupTable[c][0] >= 2 ? 1 : 0;
|
||||||
off2y = lookupTable4D[c][1] >= 2 ? 1 : 0;
|
off2y = lookupTable[c][1] >= 2 ? 1 : 0;
|
||||||
off2z = lookupTable4D[c][2] >= 2 ? 1 : 0;
|
off2z = lookupTable[c][2] >= 2 ? 1 : 0;
|
||||||
off2w = lookupTable4D[c][3] >= 2 ? 1 : 0;
|
off2w = lookupTable[c][3] >= 2 ? 1 : 0;
|
||||||
|
|
||||||
off3x = lookupTable4D[c][0] >= 1 ? 1 : 0;
|
off3x = lookupTable[c][0] >= 1 ? 1 : 0;
|
||||||
off3y = lookupTable4D[c][1] >= 1 ? 1 : 0;
|
off3y = lookupTable[c][1] >= 1 ? 1 : 0;
|
||||||
off3z = lookupTable4D[c][2] >= 1 ? 1 : 0;
|
off3z = lookupTable[c][2] >= 1 ? 1 : 0;
|
||||||
off3w = lookupTable4D[c][3] >= 1 ? 1 : 0;
|
off3w = lookupTable[c][3] >= 1 ? 1 : 0;
|
||||||
|
|
||||||
d1x = unskewedDistToOriginx;
|
d1x = unskewedDistToOriginx;
|
||||||
d1y = unskewedDistToOriginy;
|
d1y = unskewedDistToOriginy;
|
||||||
d1z = unskewedDistToOriginz;
|
d1z = unskewedDistToOriginz;
|
||||||
d1w = unskewedDistToOriginw;
|
d1w = unskewedDistToOriginw;
|
||||||
|
|
||||||
d2x = d1x - off1x + UnskewCoeff4D;
|
d2x = d1x - off1x + s_UnskewCoeff4D;
|
||||||
d2y = d1y - off1y + UnskewCoeff4D;
|
d2y = d1y - off1y + s_UnskewCoeff4D;
|
||||||
d2z = d1z - off1z + UnskewCoeff4D;
|
d2z = d1z - off1z + s_UnskewCoeff4D;
|
||||||
d2w = d1w - off1w + UnskewCoeff4D;
|
d2w = d1w - off1w + s_UnskewCoeff4D;
|
||||||
|
|
||||||
d3x = d1x - off2x + 2.f*UnskewCoeff4D;
|
d3x = d1x - off2x + 2.f*s_UnskewCoeff4D;
|
||||||
d3y = d1y - off2y + 2.f*UnskewCoeff4D;
|
d3y = d1y - off2y + 2.f*s_UnskewCoeff4D;
|
||||||
d3z = d1z - off2z + 2.f*UnskewCoeff4D;
|
d3z = d1z - off2z + 2.f*s_UnskewCoeff4D;
|
||||||
d3w = d1w - off2w + 2.f*UnskewCoeff4D;
|
d3w = d1w - off2w + 2.f*s_UnskewCoeff4D;
|
||||||
|
|
||||||
d4x = d1x - off3x + 3.f*UnskewCoeff4D;
|
d4x = d1x - off3x + 3.f*s_UnskewCoeff4D;
|
||||||
d4y = d1y - off3y + 3.f*UnskewCoeff4D;
|
d4y = d1y - off3y + 3.f*s_UnskewCoeff4D;
|
||||||
d4z = d1z - off3z + 3.f*UnskewCoeff4D;
|
d4z = d1z - off3z + 3.f*s_UnskewCoeff4D;
|
||||||
d4w = d1w - off3w + 3.f*UnskewCoeff4D;
|
d4w = d1w - off3w + 3.f*s_UnskewCoeff4D;
|
||||||
|
|
||||||
d5x = d1x - 1.f + 4*UnskewCoeff4D;
|
d5x = d1x - 1.f + 4*s_UnskewCoeff4D;
|
||||||
d5y = d1y - 1.f + 4*UnskewCoeff4D;
|
d5y = d1y - 1.f + 4*s_UnskewCoeff4D;
|
||||||
d5z = d1z - 1.f + 4*UnskewCoeff4D;
|
d5z = d1z - 1.f + 4*s_UnskewCoeff4D;
|
||||||
d5w = d1w - 1.f + 4*UnskewCoeff4D;
|
d5w = d1w - 1.f + 4*s_UnskewCoeff4D;
|
||||||
|
|
||||||
ii = skewedCubeOriginx & 255;
|
ii = skewedCubeOriginx & 255;
|
||||||
jj = skewedCubeOriginy & 255;
|
jj = skewedCubeOriginy & 255;
|
||||||
kk = skewedCubeOriginz & 255;
|
kk = skewedCubeOriginz & 255;
|
||||||
ll = skewedCubeOriginw & 255;
|
ll = skewedCubeOriginw & 255;
|
||||||
|
|
||||||
gi0 = perm[ii + perm[jj + perm[kk + perm[ll ]]]] & 31;
|
gi0 = m_permutations[ii + m_permutations[jj + m_permutations[kk + m_permutations[ll ]]]] & 31;
|
||||||
gi1 = perm[ii + off1x + perm[jj + off1y + perm[kk + off1z + perm[ll + off1w]]]] & 31;
|
gi1 = m_permutations[ii + off1x + m_permutations[jj + off1y + m_permutations[kk + off1z + m_permutations[ll + off1w]]]] & 31;
|
||||||
gi2 = perm[ii + off2x + perm[jj + off2y + perm[kk + off2z + perm[ll + off2w]]]] & 31;
|
gi2 = m_permutations[ii + off2x + m_permutations[jj + off2y + m_permutations[kk + off2z + m_permutations[ll + off2w]]]] & 31;
|
||||||
gi3 = perm[ii + off3x + perm[jj + off3y + perm[kk + off3z + perm[ll + off3w]]]] & 31;
|
gi3 = m_permutations[ii + off3x + m_permutations[jj + off3y + m_permutations[kk + off3z + m_permutations[ll + off3w]]]] & 31;
|
||||||
gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1 ]]]] % 32;
|
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;
|
c1 = 0.6f - d1x*d1x - d1y*d1y - d1z*d1z - d1w*d1w;
|
||||||
c2 = 0.6f - d2x*d2x - d2y*d2y - d2z*d2z - d2w*d2w;
|
c2 = 0.6f - d2x*d2x - d2y*d2y - d2z*d2z - d2w*d2w;
|
||||||
|
|
@ -432,27 +348,27 @@ namespace Nz
|
||||||
if(c1 < 0)
|
if(c1 < 0)
|
||||||
n1 = 0;
|
n1 = 0;
|
||||||
else
|
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)
|
if(c2 < 0)
|
||||||
n2 = 0;
|
n2 = 0;
|
||||||
else
|
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)
|
if(c3 < 0)
|
||||||
n3 = 0;
|
n3 = 0;
|
||||||
else
|
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)
|
if(c4 < 0)
|
||||||
n4 = 0;
|
n4 = 0;
|
||||||
else
|
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)
|
if(c5 < 0)
|
||||||
n5 = 0;
|
n5 = 0;
|
||||||
else
|
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;
|
return (n1+n2+n3+n4+n5)*27.f;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,56 +10,38 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
Worley::Worley() :
|
namespace
|
||||||
scales{
|
{
|
||||||
1.f / std::sqrt(2),
|
static constexpr std::array<float, 4> m_functionScales =
|
||||||
0.5f / std::sqrt(2),
|
{
|
||||||
0.5f / std::sqrt(2),
|
1.f / M_SQRT2,
|
||||||
0.5f / std::sqrt(2)
|
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);
|
SetSeed(seed);
|
||||||
Shuffle();
|
Shuffle();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Worley::Set(WorleyFunction func)
|
float Worley::Get(float x, float y, float scale) const
|
||||||
{
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
std::map<float, Vector2f> featurePoints;
|
std::map<float, Vector2f> featurePoints;
|
||||||
std::map<float, Vector2f>::iterator it;
|
|
||||||
|
|
||||||
float xc, yc;
|
float xc, yc;
|
||||||
int x0, y0;
|
int x0, y0;
|
||||||
float fractx, fracty;
|
float fractx, fracty;
|
||||||
|
|
||||||
std::initializer_list<float>::const_iterator c = coordinates.begin();
|
xc = x * scale;
|
||||||
|
yc = y * scale;
|
||||||
xc = *(c ) * scale;
|
|
||||||
yc = *(++c) * scale;
|
|
||||||
|
|
||||||
x0 = fastfloor(xc);
|
x0 = fastfloor(xc);
|
||||||
y0 = fastfloor(yc);
|
y0 = fastfloor(yc);
|
||||||
|
|
@ -69,83 +51,83 @@ namespace Nz
|
||||||
|
|
||||||
featurePoints.clear();
|
featurePoints.clear();
|
||||||
|
|
||||||
_SquareTest(x0,y0,xc,yc,featurePoints);
|
SquareTest(x0,y0,xc,yc,featurePoints);
|
||||||
|
|
||||||
it = featurePoints.begin();
|
auto it = featurePoints.begin();
|
||||||
std::advance(it,function);
|
std::advance(it, m_function);
|
||||||
|
|
||||||
if(fractx < it->first)
|
if(fractx < it->first)
|
||||||
_SquareTest(x0 - 1,y0,xc,yc,featurePoints);
|
SquareTest(x0 - 1,y0,xc,yc,featurePoints);
|
||||||
|
|
||||||
it = featurePoints.begin();
|
it = featurePoints.begin();
|
||||||
std::advance(it,function);
|
std::advance(it, m_function);
|
||||||
|
|
||||||
if(1.f - fractx < it->first)
|
if(1.f - fractx < it->first)
|
||||||
_SquareTest(x0 + 1,y0,xc,yc,featurePoints);
|
SquareTest(x0 + 1,y0,xc,yc,featurePoints);
|
||||||
|
|
||||||
it = featurePoints.begin();
|
it = featurePoints.begin();
|
||||||
std::advance(it,function);
|
std::advance(it, m_function);
|
||||||
|
|
||||||
if(fracty < it->first)
|
if(fracty < it->first)
|
||||||
_SquareTest(x0,y0 - 1,xc,yc,featurePoints);
|
SquareTest(x0,y0 - 1,xc,yc,featurePoints);
|
||||||
|
|
||||||
it = featurePoints.begin();
|
it = featurePoints.begin();
|
||||||
std::advance(it,function);
|
std::advance(it, m_function);
|
||||||
|
|
||||||
if(1.f - fracty < it->first)
|
if (1.f - fracty < it->first)
|
||||||
_SquareTest(x0,y0 + 1,xc,yc,featurePoints);
|
SquareTest(x0,y0 + 1,xc,yc,featurePoints);
|
||||||
|
|
||||||
it = featurePoints.begin();
|
it = featurePoints.begin();
|
||||||
std::advance(it,function);
|
std::advance(it, m_function);
|
||||||
|
|
||||||
if(fractx < it->first &&
|
if (fractx < it->first && fracty < it->first)
|
||||||
fracty < it->first)
|
SquareTest(x0 - 1, y0 - 1,xc,yc,featurePoints);
|
||||||
_SquareTest(x0 - 1, y0 - 1,xc,yc,featurePoints);
|
|
||||||
|
|
||||||
it = featurePoints.begin();
|
it = featurePoints.begin();
|
||||||
std::advance(it,function);
|
std::advance(it, m_function);
|
||||||
|
|
||||||
if(1.f - fractx < it->first &&
|
if (1.f - fractx < it->first && fracty < it->first)
|
||||||
fracty < it->first)
|
SquareTest(x0 + 1, y0 - 1,xc,yc,featurePoints);
|
||||||
_SquareTest(x0 + 1, y0 - 1,xc,yc,featurePoints);
|
|
||||||
|
|
||||||
it = featurePoints.begin();
|
it = featurePoints.begin();
|
||||||
std::advance(it,function);
|
std::advance(it, m_function);
|
||||||
|
|
||||||
if(fractx < it->first &&
|
if (fractx < it->first && 1.f - fracty < it->first)
|
||||||
1.f - fracty < it->first)
|
SquareTest(x0 - 1, y0 + 1,xc,yc,featurePoints);
|
||||||
_SquareTest(x0 - 1, y0 + 1,xc,yc,featurePoints);
|
|
||||||
|
|
||||||
it = featurePoints.begin();
|
it = featurePoints.begin();
|
||||||
std::advance(it,function);
|
std::advance(it, m_function);
|
||||||
|
|
||||||
if(1.f - fractx < it->first &&
|
if(1.f - fractx < it->first && 1.f - fracty < it->first)
|
||||||
1.f - fracty < it->first)
|
SquareTest(x0 + 1, y0 + 1,xc,yc,featurePoints);
|
||||||
_SquareTest(x0 + 1, y0 + 1,xc,yc,featurePoints);
|
|
||||||
|
|
||||||
it = featurePoints.begin();
|
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.");
|
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.");
|
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 ii = xi & 255;
|
||||||
int jj = yi & 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
|
//On initialise notre rng avec seed
|
||||||
std::minstd_rand0 randomNumberGenerator(seed);
|
std::minstd_rand0 randomNumberGenerator(seed);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue