-
-
Save Markyparky56/e0fd43e847ac53068603130df3e8e560 to your computer and use it in GitHub Desktop.
#pragma once | |
/******************************************************************************* | |
OpenSimplex Noise in C++ | |
Ported from https://gist.github.com/digitalshadow/134a3a02b67cecd72181 | |
Originally from https://gist.github.com/KdotJPG/b1270127455a94ac5d19 | |
Optimised by DigitalShadow | |
This version by Mark A. Ropper (Markyparky56) | |
*******************************************************************************/ | |
#include <array> | |
#include <vector> | |
#include <memory> // unique_ptr | |
#include <ctime> // time for random seed | |
#if defined(__clang__) // Couldn't find one for clang | |
#define FORCE_INLINE inline | |
#elif defined(__GNUC__) || defined(__GNUG__) | |
#define FORCE_INLINE __attribute__((always_inline)) | |
#elif defined(_MSC_VER) | |
#define FORCE_INLINE __forceinline | |
#endif | |
class OpenSimplexNoise | |
{ | |
friend class StaticConstructor; | |
protected: | |
// Contribution structs | |
struct Contribution2 | |
{ | |
public: | |
double dx, dy; | |
int xsb, ysb; | |
Contribution2 *Next; | |
Contribution2(double multiplier, int _xsb, int _ysb) | |
: xsb(_xsb) | |
, ysb(_ysb) | |
, Next(nullptr) | |
{ | |
dx = -_xsb - multiplier * SQUISH_2D; | |
dy = -_ysb - multiplier * SQUISH_2D; | |
} | |
~Contribution2() | |
{ | |
if (Next != nullptr) | |
{ | |
delete Next; | |
} | |
} | |
}; | |
using pContribution2 = std::unique_ptr<Contribution2>; | |
struct Contribution3 | |
{ | |
public: | |
double dx, dy, dz; | |
int xsb, ysb, zsb; | |
Contribution3 *Next; | |
Contribution3(double multiplier, int _xsb, int _ysb, int _zsb) | |
: xsb(_xsb) | |
, ysb(_ysb) | |
, zsb(_zsb) | |
, Next(nullptr) | |
{ | |
dx = -xsb - multiplier * SQUISH_3D; | |
dy = -ysb - multiplier * SQUISH_3D; | |
dz = -zsb - multiplier * SQUISH_3D; | |
} | |
~Contribution3() | |
{ | |
if (Next != nullptr) | |
{ | |
delete Next; | |
} | |
} | |
}; | |
using pContribution3 = std::unique_ptr<Contribution3>; | |
struct Contribution4 | |
{ | |
public: | |
double dx, dy, dz, dw; | |
int xsb, ysb, zsb, wsb; | |
Contribution4 *Next; | |
Contribution4(double multiplier, int _xsb, int _ysb, int _zsb, int _wsb) | |
: xsb(_xsb) | |
, ysb(_ysb) | |
, zsb(_zsb) | |
, wsb(_wsb) | |
, Next(nullptr) | |
{ | |
dx = -xsb - multiplier * SQUISH_4D; | |
dy = -ysb - multiplier * SQUISH_4D; | |
dz = -zsb - multiplier * SQUISH_4D; | |
dw = -wsb - multiplier * SQUISH_4D; | |
} | |
~Contribution4() | |
{ | |
if (Next != nullptr) | |
{ | |
delete Next; | |
} | |
} | |
}; | |
using pContribution4 = std::unique_ptr<Contribution4>; | |
// Constants | |
static const double STRETCH_2D; | |
static const double STRETCH_3D; | |
static const double STRETCH_4D; | |
static const double SQUISH_2D; | |
static const double SQUISH_3D; | |
static const double SQUISH_4D; | |
static const double NORM_2D; | |
static const double NORM_3D; | |
static const double NORM_4D; | |
std::array<unsigned char, 256> perm; | |
std::array<unsigned char, 256> perm2D; | |
std::array<unsigned char, 256> perm3D; | |
std::array<unsigned char, 256> perm4D; | |
static std::array<double, 16> gradients2D; | |
static std::array<double, 72> gradients3D; | |
static std::array<double, 256> gradients4D; | |
static std::vector<Contribution2*> lookup2D; | |
static std::vector<Contribution3*> lookup3D; | |
static std::vector<Contribution4*> lookup4D; | |
static std::vector<pContribution2> contributions2D; | |
static std::vector<pContribution3> contributions3D; | |
static std::vector<pContribution4> contributions4D; | |
struct StaticConstructor | |
{ | |
StaticConstructor() | |
{ | |
gradients2D = | |
{ | |
5, 2, 2, 5, | |
-5, 2, -2, 5, | |
5, -2, 2, -5, | |
-5, -2, -2, -5, | |
}; | |
gradients3D = | |
{ | |
-11, 4, 4, -4, 11, 4, -4, 4, 11, | |
11, 4, 4, 4, 11, 4, 4, 4, 11, | |
-11, -4, 4, -4, -11, 4, -4, -4, 11, | |
11, -4, 4, 4, -11, 4, 4, -4, 11, | |
-11, 4, -4, -4, 11, -4, -4, 4, -11, | |
11, 4, -4, 4, 11, -4, 4, 4, -11, | |
-11, -4, -4, -4, -11, -4, -4, -4, -11, | |
11, -4, -4, 4, -11, -4, 4, -4, -11, | |
}; | |
gradients4D = | |
{ | |
3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, | |
-3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, | |
3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, 1, 1, -1, 1, 3, | |
-3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, | |
3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, 1, 1, 1, -1, 3, | |
-3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, | |
3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, 1, 1, -1, -1, 3, | |
-3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, | |
3, 1, 1, -1, 1, 3, 1, -1, 1, 1, 3, -1, 1, 1, 1, -3, | |
-3, 1, 1, -1, -1, 3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, | |
3, -1, 1, -1, 1, -3, 1, -1, 1, -1, 3, -1, 1, -1, 1, -3, | |
-3, -1, 1, -1, -1, -3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, | |
3, 1, -1, -1, 1, 3, -1, -1, 1, 1, -3, -1, 1, 1, -1, -3, | |
-3, 1, -1, -1, -1, 3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, | |
3, -1, -1, -1, 1, -3, -1, -1, 1, -1, -3, -1, 1, -1, -1, -3, | |
-3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, -1, -1, -1, -1, -3, | |
}; | |
// Create Contribution2s for lookup2D | |
std::vector<std::vector<int>> base2D = | |
{ | |
{ 1, 1, 0, 1, 0, 1, 0, 0, 0 }, | |
{ 1, 1, 0, 1, 0, 1, 2, 1, 1 } | |
}; | |
std::vector<int> p2D = | |
{ | |
0, 0, 1, -1, 0, 0, -1, 1, 0, 2, 1, 1, 1, 2, 2, 0, 1, 2, 0, 2, 1, 0, 0, 0 | |
}; | |
std::vector<int> lookupPairs2D = | |
{ | |
0, 1, 1, 0, 4, 1, 17, 0, 20, 2, 21, 2, 22, 5, 23, 5, 26, 4, 39, 3, 42, 4, 43, 3 | |
}; | |
contributions2D.resize(6); | |
for (int i = 0; i < static_cast<int>(p2D.size()); i += 4) | |
{ | |
std::vector<int> baseSet = base2D[p2D[i]]; | |
Contribution2 *previous = nullptr, *current = nullptr; | |
for (int k = 0; k < static_cast<int>(baseSet.size()); k += 3) | |
{ | |
current = | |
new Contribution2(baseSet[k], baseSet[k + 1], baseSet[k + 2]); | |
if (previous == nullptr) | |
{ | |
contributions2D[i / 4].reset(current); | |
} | |
else | |
{ | |
previous->Next = current; | |
} | |
previous = current; | |
} | |
current->Next = new Contribution2(p2D[i + 1], p2D[i + 2], p2D[i + 3]); | |
} | |
lookup2D.resize(64); | |
for (int i = 0; i < static_cast<int>(lookupPairs2D.size()); i += 2) | |
{ | |
lookup2D[lookupPairs2D[i]] = | |
contributions2D[lookupPairs2D[i + 1]].get(); | |
} | |
// Create Contribution3s for lookup3D | |
std::vector<std::vector<int>> base3D = | |
{ | |
{ 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1 }, | |
{ 2, 1, 1, 0, 2, 1, 0, 1, 2, 0, 1, 1, 3, 1, 1, 1 }, | |
{ 1, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 2, 1, 1, 0, 2, 1, 0, 1, 2, 0, 1, 1 } | |
}; | |
std::vector<int> p3D = | |
{ | |
0, 0, 1, -1, 0, 0, 1, 0, -1, 0, 0, -1, 1, 0, 0, 0, 1, -1, 0, 0, -1, 0, 1, 0, 0, -1, 1, 0, 2, 1, 1, 0, 1, 1, 1, -1, 0, 2, 1, 0, 1, 1, 1, -1, 1, 0, 2, 0, 1, 1, 1, -1, 1, 1, 1, 3, 2, 1, 0, 3, 1, 2, 0, 1, 3, 2, 0, 1, 3, 1, 0, 2, 1, 3, 0, 2, 1, 3, 0, 1, 2, 1, 1, 1, 0, 0, 2, 2, 0, 0, 1, 1, 0, 1, 0, 2, 0, 2, 0, 1, 1, 0, 0, 1, 2, 0, 0, 2, 2, 0, 0, 0, 0, 1, 1, -1, 1, 2, 0, 0, 0, 0, 1, -1, 1, 1, 2, 0, 0, 0, 0, 1, 1, 1, -1, 2, 3, 1, 1, 1, 2, 0, 0, 2, 2, 3, 1, 1, 1, 2, 2, 0, 0, 2, 3, 1, 1, 1, 2, 0, 2, 0, 2, 1, 1, -1, 1, 2, 0, 0, 2, 2, 1, 1, -1, 1, 2, 2, 0, 0, 2, 1, -1, 1, 1, 2, 0, 0, 2, 2, 1, -1, 1, 1, 2, 0, 2, 0, 2, 1, 1, 1, -1, 2, 2, 0, 0, 2, 1, 1, 1, -1, 2, 0, 2, 0 | |
}; | |
std::vector<int> lookupPairs3D = | |
{ | |
0, 2, 1, 1, 2, 2, 5, 1, 6, 0, 7, 0, 32, 2, 34, 2, 129, 1, 133, 1, 160, 5, 161, 5, 518, 0, 519, 0, 546, 4, 550, 4, 645, 3, 647, 3, 672, 5, 673, 5, 674, 4, 677, 3, 678, 4, 679, 3, 680, 13, 681, 13, 682, 12, 685, 14, 686, 12, 687, 14, 712, 20, 714, 18, 809, 21, 813, 23, 840, 20, 841, 21, 1198, 19, 1199, 22, 1226, 18, 1230, 19, 1325, 23, 1327, 22, 1352, 15, 1353, 17, 1354, 15, 1357, 17, 1358, 16, 1359, 16, 1360, 11, 1361, 10, 1362, 11, 1365, 10, 1366, 9, 1367, 9, 1392, 11, 1394, 11, 1489, 10, 1493, 10, 1520, 8, 1521, 8, 1878, 9, 1879, 9, 1906, 7, 1910, 7, 2005, 6, 2007, 6, 2032, 8, 2033, 8, 2034, 7, 2037, 6, 2038, 7, 2039, 6 | |
}; | |
contributions3D.resize(p3D.size() / 9); | |
for (int i = 0; i < static_cast<int>(p3D.size()); i += 9) | |
{ | |
auto baseSet = base3D[p3D[i]]; | |
Contribution3 *previous = nullptr, *current = nullptr; | |
for (int k = 0; k < static_cast<int>(baseSet.size()); k += 4) | |
{ | |
current = | |
new Contribution3(baseSet[k], baseSet[k + 1], | |
baseSet[k + 2], baseSet[k + 3]); | |
if (previous == nullptr) | |
{ | |
contributions3D[i / 9] = pContribution3(current); | |
} | |
else | |
{ | |
previous->Next = current; | |
} | |
previous = current; | |
} | |
current->Next = new Contribution3(p3D[i + 1], p3D[i + 2], p3D[i + 3], p3D[i + 4]); | |
current->Next->Next = new Contribution3(p3D[i + 5], p3D[i + 6], p3D[i + 7], p3D[i + 8]); | |
} | |
lookup3D.resize(2048); | |
for (int i = 0; i < static_cast<int>(lookupPairs3D.size()); i += 2) | |
{ | |
lookup3D[lookupPairs3D[i]] = | |
contributions3D[lookupPairs3D[i + 1]].get(); | |
} | |
// Create Contribution4s for lookup4D | |
std::vector<std::vector<int>> base4D = | |
{ | |
{ 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1 }, | |
{ 3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 4, 1, 1, 1, 1 }, | |
{ 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1 }, | |
{ 3, 1, 1, 1, 0, 3, 1, 1, 0, 1, 3, 1, 0, 1, 1, 3, 0, 1, 1, 1, 2, 1, 1, 0, 0, 2, 1, 0, 1, 0, 2, 1, 0, 0, 1, 2, 0, 1, 1, 0, 2, 0, 1, 0, 1, 2, 0, 0, 1, 1 } | |
}; | |
std::vector<int> p4D = | |
{ | |
0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, 0, 1, 0, -1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 0, 0, 0, 1, -1, 0, 0, -1, 0, 0, 1, 0, 0, -1, 0, 1, 0, 0, 0, -1, 1, 0, 2, 1, 1, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 2, 1, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 0, 2, 0, 1, 1, 0, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 2, 1, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 2, 0, 1, 0, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 2, 0, 0, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 1, 4, 2, 1, 1, 0, 4, 1, 2, 1, 0, 4, 1, 1, 2, 0, 1, 4, 2, 1, 0, 1, 4, 1, 2, 0, 1, 4, 1, 1, 0, 2, 1, 4, 2, 0, 1, 1, 4, 1, 0, 2, 1, 4, 1, 0, 1, 2, 1, 4, 0, 2, 1, 1, 4, 0, 1, 2, 1, 4, 0, 1, 1, 2, 1, 2, 1, 1, 0, 0, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 1, 2, 1, 0, 1, 0, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 1, 2, 0, 1, 1, 0, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 1, 2, 1, 0, 0, 1, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 1, 2, 0, 1, 0, 1, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 1, 2, 0, 0, 1, 1, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 2, 0, 0, 0, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 2, 0, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 2, 0, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 2, 0, 0, 2, 3, 1, 1, 1, 0, 2, 1, 1, 1, -1, 2, 0, 0, 2, 0, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 2, 0, 2, 3, 1, 1, 0, 1, 2, 1, 1, -1, 1, 2, 0, 0, 0, 2, 2, 3, 1, 0, 1, 1, 2, 1, -1, 1, 1, 2, 0, 0, 0, 2, 2, 3, 0, 1, 1, 1, 2, -1, 1, 1, 1, 2, 0, 0, 0, 2, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 0, 0, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 0, 0, 0, 0, 0, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 0, 0, 0, 0, 0, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 2, 2, 0, 0, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 2, 0, 0, 0, 2, 1, 1, 1, -1, 0, 1, 1, 1, 0, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 2, 0, 0, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 0, 1, 1, 0, 1, -1, 2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 0, 1, 0, 1, 1, -1, 2, 0, 0, 2, 0, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 2, 0, 2, 1, 1, -1, 0, 1, 1, 1, 0, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 0, 1, 1, 0, 1, -1, 1, 2, 0, 0, 0, 2, 2, 1, -1, 0, 1, 1, 1, 0, -1, 1, 1, 2, 0, 0, 0, 2, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, 1, -1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, 1, -1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, 1, 1, -1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, 1, 1, -1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, 1, -1, 1, 3, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, 1, -1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, 1, -1, 1, 1, 3, 1, 0, 1, 0, 0, 2, 0, 2, 0, 0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 1, 0, 2, 0, 0, 2, 0, 2, -1, 1, 1, 1, 3, 1, 0, 0, 0, 1, 2, 0, 0, 0, 2, 2, -1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 4, 1, 1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 4, 1, 1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 4, 1, 1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 4, 1, 1, 1, 1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, 1, -1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 2, 1, 1, 1, -1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, 1, 1, 1, -1, 3, 3, 2, 1, 0, 0, 3, 1, 2, 0, 0, 2, 1, 1, -1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, 1, -1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 2, 1, 1, -1, 1, 3, 3, 2, 0, 1, 0, 3, 1, 0, 2, 0, 2, 1, -1, 1, 1, 3, 3, 2, 0, 0, 1, 3, 1, 0, 0, 2, 2, 1, -1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, 1, -1, 1, 1, 3, 3, 0, 2, 1, 0, 3, 0, 1, 2, 0, 2, -1, 1, 1, 1, 3, 3, 0, 2, 0, 1, 3, 0, 1, 0, 2, 2, -1, 1, 1, 1, 3, 3, 0, 0, 2, 1, 3, 0, 0, 1, 2, 2, -1, 1, 1, 1 | |
}; | |
std::vector<int> lookupPairs4D = | |
{ | |
0, 3, 1, 2, 2, 3, 5, 2, 6, 1, 7, 1, 8, 3, 9, 2, 10, 3, 13, 2, 16, 3, 18, 3, 22, 1, 23, 1, 24, 3, 26, 3, 33, 2, 37, 2, 38, 1, 39, 1, 41, 2, 45, 2, 54, 1, 55, 1, 56, 0, 57, 0, 58, 0, 59, 0, 60, 0, 61, 0, 62, 0, 63, 0, 256, 3, 258, 3, 264, 3, 266, 3, 272, 3, 274, 3, 280, 3, 282, 3, 2049, 2, 2053, 2, 2057, 2, 2061, 2, 2081, 2, 2085, 2, 2089, 2, 2093, 2, 2304, 9, 2305, 9, 2312, 9, 2313, 9, 16390, 1, 16391, 1, 16406, 1, 16407, 1, 16422, 1, 16423, 1, 16438, 1, 16439, 1, 16642, 8, 16646, 8, 16658, 8, 16662, 8, 18437, 6, 18439, 6, 18469, 6, 18471, 6, 18688, 9, 18689, 9, 18690, 8, 18693, 6, 18694, 8, 18695, 6, 18696, 9, 18697, 9, 18706, 8, 18710, 8, 18725, 6, 18727, 6, 131128, 0, 131129, 0, 131130, 0, 131131, 0, 131132, 0, 131133, 0, 131134, 0, 131135, 0, 131352, 7, 131354, 7, 131384, 7, 131386, 7, 133161, 5, 133165, 5, 133177, 5, 133181, 5, 133376, 9, 133377, 9, 133384, 9, 133385, 9, 133400, 7, 133402, 7, 133417, 5, 133421, 5, 133432, 7, 133433, 5, 133434, 7, 133437, 5, 147510, 4, 147511, 4, 147518, 4, 147519, 4, 147714, 8, 147718, 8, 147730, 8, 147734, 8, 147736, 7, 147738, 7, 147766, 4, 147767, 4, 147768, 7, 147770, 7, 147774, 4, 147775, 4, 149509, 6, 149511, 6, 149541, 6, 149543, 6, 149545, 5, 149549, 5, 149558, 4, 149559, 4, 149561, 5, 149565, 5, 149566, 4, 149567, 4, 149760, 9, 149761, 9, 149762, 8, 149765, 6, 149766, 8, 149767, 6, 149768, 9, 149769, 9, 149778, 8, 149782, 8, 149784, 7, 149786, 7, 149797, 6, 149799, 6, 149801, 5, 149805, 5, 149814, 4, 149815, 4, 149816, 7, 149817, 5, 149818, 7, 149821, 5, 149822, 4, 149823, 4, 149824, 37, 149825, 37, 149826, 36, 149829, 34, 149830, 36, 149831, 34, 149832, 37, 149833, 37, 149842, 36, 149846, 36, 149848, 35, 149850, 35, 149861, 34, 149863, 34, 149865, 33, 149869, 33, 149878, 32, 149879, 32, 149880, 35, 149881, 33, 149882, 35, 149885, 33, 149886, 32, 149887, 32, 150080, 49, 150082, 48, 150088, 49, 150098, 48, 150104, 47, 150106, 47, 151873, 46, 151877, 45, 151881, 46, 151909, 45, 151913, 44, 151917, 44, 152128, 49, 152129, 46, 152136, 49, 152137, 46, 166214, 43, 166215, 42, 166230, 43, 166247, 42, 166262, 41, 166263, 41, 166466, 48, 166470, 43, 166482, 48, 166486, 43, 168261, 45, 168263, 42, 168293, 45, 168295, 42, 168512, 31, 168513, 28, 168514, 31, 168517, 28, 168518, 25, 168519, 25, 280952, 40, 280953, 39, 280954, 40, 280957, 39, 280958, 38, 280959, 38, 281176, 47, 281178, 47, 281208, 40, 281210, 40, 282985, 44, 282989, 44, 283001, 39, 283005, 39, 283208, 30, 283209, 27, 283224, 30, 283241, 27, 283256, 22, 283257, 22, 297334, 41, 297335, 41, 297342, 38, 297343, 38, 297554, 29, 297558, 24, 297562, 29, 297590, 24, 297594, 21, 297598, 21, 299365, 26, 299367, 23, 299373, 26, 299383, 23, 299389, 20, 299391, 20, 299584, 31, 299585, 28, 299586, 31, 299589, 28, 299590, 25, 299591, 25, 299592, 30, 299593, 27, 299602, 29, 299606, 24, 299608, 30, 299610, 29, 299621, 26, 299623, 23, 299625, 27, 299629, 26, 299638, 24, 299639, 23, 299640, 22, 299641, 22, 299642, 21, 299645, 20, 299646, 21, 299647, 20, 299648, 61, 299649, 60, 299650, 61, 299653, 60, 299654, 59, 299655, 59, 299656, 58, 299657, 57, 299666, 55, 299670, 54, 299672, 58, 299674, 55, 299685, 52, 299687, 51, 299689, 57, 299693, 52, 299702, 54, 299703, 51, 299704, 56, 299705, 56, 299706, 53, 299709, 50, 299710, 53, 299711, 50, 299904, 61, 299906, 61, 299912, 58, 299922, 55, 299928, 58, 299930, 55, 301697, 60, 301701, 60, 301705, 57, 301733, 52, 301737, 57, 301741, 52, 301952, 79, 301953, 79, 301960, 76, 301961, 76, 316038, 59, 316039, 59, 316054, 54, 316071, 51, 316086, 54, 316087, 51, 316290, 78, 316294, 78, 316306, 73, 316310, 73, 318085, 77, 318087, 77, 318117, 70, 318119, 70, 318336, 79, 318337, 79, 318338, 78, 318341, 77, 318342, 78, 318343, 77, 430776, 56, 430777, 56, 430778, 53, 430781, 50, 430782, 53, 430783, 50, 431000, 75, 431002, 72, 431032, 75, 431034, 72, 432809, 74, 432813, 69, 432825, 74, 432829, 69, 433032, 76, 433033, 76, 433048, 75, 433065, 74, 433080, 75, 433081, 74, 447158, 71, 447159, 68, 447166, 71, 447167, 68, 447378, 73, 447382, 73, 447386, 72, 447414, 71, 447418, 72, 447422, 71, 449189, 70, 449191, 70, 449197, 69, 449207, 68, 449213, 69, 449215, 68, 449408, 67, 449409, 67, 449410, 66, 449413, 64, 449414, 66, 449415, 64, 449416, 67, 449417, 67, 449426, 66, 449430, 66, 449432, 65, 449434, 65, 449445, 64, 449447, 64, 449449, 63, 449453, 63, 449462, 62, 449463, 62, 449464, 65, 449465, 63, 449466, 65, 449469, 63, 449470, 62, 449471, 62, 449472, 19, 449473, 19, 449474, 18, 449477, 16, 449478, 18, 449479, 16, 449480, 19, 449481, 19, 449490, 18, 449494, 18, 449496, 17, 449498, 17, 449509, 16, 449511, 16, 449513, 15, 449517, 15, 449526, 14, 449527, 14, 449528, 17, 449529, 15, 449530, 17, 449533, 15, 449534, 14, 449535, 14, 449728, 19, 449729, 19, 449730, 18, 449734, 18, 449736, 19, 449737, 19, 449746, 18, 449750, 18, 449752, 17, 449754, 17, 449784, 17, 449786, 17, 451520, 19, 451521, 19, 451525, 16, 451527, 16, 451528, 19, 451529, 19, 451557, 16, 451559, 16, 451561, 15, 451565, 15, 451577, 15, 451581, 15, 451776, 19, 451777, 19, 451784, 19, 451785, 19, 465858, 18, 465861, 16, 465862, 18, 465863, 16, 465874, 18, 465878, 18, 465893, 16, 465895, 16, 465910, 14, 465911, 14, 465918, 14, 465919, 14, 466114, 18, 466118, 18, 466130, 18, 466134, 18, 467909, 16, 467911, 16, 467941, 16, 467943, 16, 468160, 13, 468161, 13, 468162, 13, 468163, 13, 468164, 13, 468165, 13, 468166, 13, 468167, 13, 580568, 17, 580570, 17, 580585, 15, 580589, 15, 580598, 14, 580599, 14, 580600, 17, 580601, 15, 580602, 17, 580605, 15, 580606, 14, 580607, 14, 580824, 17, 580826, 17, 580856, 17, 580858, 17, 582633, 15, 582637, 15, 582649, 15, 582653, 15, 582856, 12, 582857, 12, 582872, 12, 582873, 12, 582888, 12, 582889, 12, 582904, 12, 582905, 12, 596982, 14, 596983, 14, 596990, 14, 596991, 14, 597202, 11, 597206, 11, 597210, 11, 597214, 11, 597234, 11, 597238, 11, 597242, 11, 597246, 11, 599013, 10, 599015, 10, 599021, 10, 599023, 10, 599029, 10, 599031, 10, 599037, 10, 599039, 10, 599232, 13, 599233, 13, 599234, 13, 599235, 13, 599236, 13, 599237, 13, 599238, 13, 599239, 13, 599240, 12, 599241, 12, 599250, 11, 599254, 11, 599256, 12, 599257, 12, 599258, 11, 599262, 11, 599269, 10, 599271, 10, 599272, 12, 599273, 12, 599277, 10, 599279, 10, 599282, 11, 599285, 10, 599286, 11, 599287, 10, 599288, 12, 599289, 12, 599290, 11, 599293, 10, 599294, 11, 599295, 10 | |
}; | |
contributions4D.resize(p4D.size() / 16); | |
for (int i = 0; i < static_cast<int>(p4D.size()); i += 16) | |
{ | |
auto baseSet = base4D[p4D[i]]; | |
Contribution4 *previous = nullptr, *current = nullptr; | |
for (int k = 0; k < static_cast<int>(baseSet.size()); k += 5) | |
{ | |
current = | |
new Contribution4(baseSet[k], baseSet[k + 1], | |
baseSet[k + 2], baseSet[k + 3], | |
baseSet[k + 4]); | |
if (previous == nullptr) | |
{ | |
contributions4D[i / 16] = pContribution4(current); | |
} | |
else | |
{ | |
previous->Next = current; | |
} | |
previous = current; | |
} | |
current->Next = | |
new Contribution4(p4D[i + 1], p4D[i + 2], | |
p4D[i + 3], p4D[i + 4], p4D[i + 5]); | |
current->Next->Next = | |
new Contribution4(p4D[i + 6], p4D[i + 7], | |
p4D[i + 8], p4D[i + 9], p4D[i + 10]); | |
current->Next->Next->Next = | |
new Contribution4(p4D[i + 11], p4D[i + 12], | |
p4D[i + 13], p4D[i + 14], p4D[i + 15]); | |
} | |
lookup4D.resize(1048576); | |
for (int i = 0; i < static_cast<int>(lookupPairs4D.size()); i += 2) | |
{ | |
lookup4D[lookupPairs4D[i]] = | |
contributions4D[lookupPairs4D[i+1]].get(); | |
} | |
} | |
}; | |
static StaticConstructor staticConstructor; | |
FORCE_INLINE static int FastFloor(double x) | |
{ | |
int xi = static_cast<int>(x); | |
return x < xi ? xi - 1 : xi; | |
} | |
public: | |
OpenSimplexNoise() | |
: OpenSimplexNoise(static_cast<int64_t>(time(nullptr))) | |
{} | |
OpenSimplexNoise(int64_t seed) | |
{ | |
std::array<char, 256> source; | |
for (int i = 0; i < 256; i++) | |
{ | |
source[i] = i; | |
} | |
seed = seed * 6364136223846793005L + 1442695040888963407L; | |
seed = seed * 6364136223846793005L + 1442695040888963407L; | |
seed = seed * 6364136223846793005L + 1442695040888963407L; | |
for (int i = 255; i >= 0; i--) | |
{ | |
seed = seed * 6364136223846793005L + 1442695040888963407L; | |
int r = static_cast<int>((seed + 31) % (i + 1)); | |
if (r < 0) | |
{ | |
r += (i + 1); | |
} | |
perm[i] = source[r]; | |
perm2D[i] = perm[i] & 0x0E; | |
perm3D[i] = (perm[i] % 24) * 3; | |
perm4D[i] = perm[i] & 0xFC; | |
source[r] = source[i]; | |
} | |
} | |
double Evaluate(double x, double y) | |
{ | |
double stretchOffset = (x + y) * STRETCH_2D; | |
double xs = x + stretchOffset; | |
double ys = y + stretchOffset; | |
int xsb = FastFloor(xs); | |
int ysb = FastFloor(ys); | |
double squishOffset = (xsb + ysb) * SQUISH_2D; | |
double dx0 = x - (xsb + squishOffset); | |
double dy0 = y - (ysb + squishOffset); | |
double xins = xs - xsb; | |
double yins = ys - ysb; | |
double inSum = xins + yins; | |
int hash = | |
static_cast<int>(xins - yins + 1) | | |
static_cast<int>(inSum) << 1 | | |
static_cast<int>(inSum + yins) << 2 | | |
static_cast<int>(inSum + xins) << 4; | |
Contribution2 *c = lookup2D[hash]; | |
double value = 0.0; | |
while (c != nullptr) | |
{ | |
double dx = dx0 + c->dx; | |
double dy = dy0 + c->dy; | |
double attn = 2 - dx * dx - dy * dy; | |
if (attn > 0) | |
{ | |
int px = xsb + c->xsb; | |
int py = ysb + c->ysb; | |
int i = perm2D[(perm[px & 0xFF] + py) & 0xFF]; | |
double valuePart = | |
gradients2D[i ] * dx | |
+ gradients2D[i + 1] * dy; | |
attn *= attn; | |
value += attn * attn * valuePart; | |
} | |
c = c->Next; | |
} | |
return value * NORM_2D; | |
} | |
double Evaluate(double x, double y, double z) | |
{ | |
double stretchOffset = (x + y + z) * STRETCH_3D; | |
double xs = x + stretchOffset; | |
double ys = y + stretchOffset; | |
double zs = z + stretchOffset; | |
int xsb = FastFloor(xs); | |
int ysb = FastFloor(ys); | |
int zsb = FastFloor(zs); | |
double squishOffset = (xsb + ysb + zsb) * SQUISH_3D; | |
double dx0 = x - (xsb + squishOffset); | |
double dy0 = y - (ysb + squishOffset); | |
double dz0 = z - (zsb + squishOffset); | |
double xins = xs - xsb; | |
double yins = ys - ysb; | |
double zins = zs - zsb; | |
double inSum = xins + yins + zins; | |
int hash = | |
static_cast<int>(yins - zins + 1) | | |
static_cast<int>(xins - yins + 1) << 1 | | |
static_cast<int>(xins - zins + 1) << 2 | | |
static_cast<int>(inSum) << 3 | | |
static_cast<int>(inSum + zins) << 5 | | |
static_cast<int>(inSum + yins) << 7 | | |
static_cast<int>(inSum + xins) << 9; | |
Contribution3 *c = lookup3D[hash]; | |
double value = 0.0; | |
while (c != nullptr) | |
{ | |
double dx = dx0 + c->dx; | |
double dy = dy0 + c->dy; | |
double dz = dz0 + c->dz; | |
double attn = 2 - dx * dx - dy * dy - dz * dz; | |
if (attn > 0) | |
{ | |
int px = xsb + c->xsb; | |
int py = ysb + c->ysb; | |
int pz = zsb + c->zsb; | |
int i = perm3D[(perm[(perm[px & 0xFF] + py) & 0xFF] + pz) & 0xFF]; | |
double valuePart = | |
gradients3D[i ] * dx | |
+ gradients3D[i + 1] * dy | |
+ gradients3D[i + 2] * dz; | |
attn *= attn; | |
value += attn * attn * valuePart; | |
} | |
c = c->Next; | |
} | |
return value * NORM_3D; | |
} | |
double Evaluate(double x, double y, double z, double w) | |
{ | |
double stretchOffset = (x + y + z + w) * STRETCH_4D; | |
double xs = x + stretchOffset; | |
double ys = y + stretchOffset; | |
double zs = z + stretchOffset; | |
double ws = w + stretchOffset; | |
int xsb = FastFloor(xs); | |
int ysb = FastFloor(ys); | |
int zsb = FastFloor(zs); | |
int wsb = FastFloor(ws); | |
double squishOffset = (xsb + ysb + zsb + wsb) * SQUISH_4D; | |
double dx0 = x - (xsb + squishOffset); | |
double dy0 = y - (ysb + squishOffset); | |
double dz0 = z - (zsb + squishOffset); | |
double dw0 = w - (wsb + squishOffset); | |
double xins = xs - xsb; | |
double yins = ys - ysb; | |
double zins = zs - zsb; | |
double wins = ws - wsb; | |
double inSum = xins + yins + zins + wins; | |
int hash = | |
static_cast<int>(zins - wins + 1) | | |
static_cast<int>(yins - zins + 1) << 1 | | |
static_cast<int>(yins - wins + 1) << 2 | | |
static_cast<int>(xins - yins + 1) << 3 | | |
static_cast<int>(xins - zins + 1) << 4 | | |
static_cast<int>(xins - wins + 1) << 5 | | |
static_cast<int>(inSum) << 6 | | |
static_cast<int>(inSum + wins) << 8 | | |
static_cast<int>(inSum + zins) << 11 | | |
static_cast<int>(inSum + yins) << 14 | | |
static_cast<int>(inSum + xins) << 17; | |
Contribution4 *c = lookup4D[hash]; | |
double value = 0.0; | |
while (c != nullptr) | |
{ | |
double dx = dx0 + c->dx; | |
double dy = dy0 + c->dy; | |
double dz = dz0 + c->dz; | |
double dw = dw0 + c->dw; | |
double attn = 2 - dx *dx - dy * dy - dz * dz - dw * dw; | |
if (attn > 0) | |
{ | |
int px = xsb + c->xsb; | |
int py = ysb + c->ysb; | |
int pz = zsb + c->zsb; | |
int pw = wsb + c->wsb; | |
int i = perm4D[( | |
perm[( | |
perm[( | |
perm[px & 0xFF] + py) & 0xFF] | |
+ pz) & 0xFF] | |
+ pw) & 0xFF]; | |
double valuePart = | |
gradients4D[i] * dx | |
+ gradients4D[i + 1] * dy | |
+ gradients4D[i + 2] * dz | |
+ gradients4D[i + 3] * dw; | |
attn *= attn; | |
value += attn * attn * valuePart; | |
} | |
c = c->Next; | |
} | |
return value * NORM_4D; | |
} | |
}; | |
#ifndef OPENSIMPLEXNOISE_STATIC_CONSTANTS | |
#define OPENSIMPLEXNOISE_STATIC_CONSTANTS | |
const double OpenSimplexNoise::STRETCH_2D = -0.211324865405187; | |
const double OpenSimplexNoise::STRETCH_3D = -1.0 / 6.0; | |
const double OpenSimplexNoise::STRETCH_4D = -0.138196601125011; | |
const double OpenSimplexNoise::SQUISH_2D = 0.366025403784439; | |
const double OpenSimplexNoise::SQUISH_3D = 1.0 / 3.0; | |
const double OpenSimplexNoise::SQUISH_4D = 0.309016994374947; | |
const double OpenSimplexNoise::NORM_2D = 1.0 / 47.0; | |
const double OpenSimplexNoise::NORM_3D = 1.0 / 103.0; | |
const double OpenSimplexNoise::NORM_4D = 1.0 / 30.0; | |
std::array<double, 16> OpenSimplexNoise::gradients2D; | |
std::array<double, 72> OpenSimplexNoise::gradients3D; | |
std::array<double, 256> OpenSimplexNoise::gradients4D; | |
std::vector<OpenSimplexNoise::Contribution2*> OpenSimplexNoise::lookup2D; | |
std::vector<OpenSimplexNoise::Contribution3*> OpenSimplexNoise::lookup3D; | |
std::vector<OpenSimplexNoise::Contribution4*> OpenSimplexNoise::lookup4D; | |
std::vector<OpenSimplexNoise::pContribution2> OpenSimplexNoise::contributions2D; | |
std::vector<OpenSimplexNoise::pContribution3> OpenSimplexNoise::contributions3D; | |
std::vector<OpenSimplexNoise::pContribution4> OpenSimplexNoise::contributions4D; | |
// Initialise our static tables | |
OpenSimplexNoise::StaticConstructor OpenSimplexNoise::staticConstructor; | |
#endif |
This is free and unencumbered software released into the public domain. | |
Anyone is free to copy, modify, publish, use, compile, sell, or | |
distribute this software, either in source code form or as a compiled | |
binary, for any purpose, commercial or non-commercial, and by any | |
means. | |
In jurisdictions that recognize copyright laws, the author or authors | |
of this software dedicate any and all copyright interest in the | |
software to the public domain. We make this dedication for the benefit | |
of the public at large and to the detriment of our heirs and | |
successors. We intend this dedication to be an overt act of | |
relinquishment in perpetuity of all present and future rights to this | |
software under copyright law. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
OTHER DEALINGS IN THE SOFTWARE. | |
For more information, please refer to <http://unlicense.org/> |
Changes with the latest revision as of 2017/03/03:
Fixed an issue with the p3D and lookupPairs3D arrays which I must have messed up when copying which caused some nasty artifacting
Put some of the arrays back on one line to reduce the line count a bit
Speed Tests!
Values are in nanoseconds, averaged from the time taken to calculate 1,000,000 points.
This is great work!
I was hoping to add some noise features (and an example) to immediate2d and this would be perfect. It doesn't look like the "UNLICENSE" file made it over from DigitalShadow's gist, so I just wanted to double-check that the same (or similar) license still applied first. Thanks!
@npiegdon the UNLICENSE file was added after I made this, I've now added it here as well. I look forward to seeing what you can do with this! If I remember right the STATIC_CONSTANTS stuff could be a bit iffy if you included it in multiple code files, so you may need to tweak how those are included. I've been working with FastNoise a lot lately, and looking at how it achieves its speed I may revisit this as I think it could benefit from some of those optimisations. P.s. replies without @ing don't notify, so if you want to contact me remember to @ me.
Is there any reason that you have everything here in a header? It would work much better if there was a header and implementation file. If I try to include it in more than one place in my project (or in a header file, in case I want an OpenSimplexNoise object as a class member) it breaks and won't compile.
@john01dav Mostly because I did not know how to do header-only files at the time, I think I know how to fix this now actually. I'll see about revising this gist ASAP.
@john01dav Mostly because I did not know how to do header-only files at the time, I think I know how to fix this now actually. I'll see about revising this gist ASAP.
header only fix (c++17): https://gist.github.com/Mashpoe/d2804c0f3647f36d2a863b22ddde9f38
Initial testing seems to be fairly good, will try to generate some pretty images tomorrow. Very promising speeds so far, remember to run without the debugger to get the most out of it.