/** | |
* K.jpg's OpenSimplex 2, smooth variant ("SuperSimplex") | |
* | |
* More language ports, as well as legacy 2014 OpenSimplex, can be found here: | |
* https://github.com/KdotJPG/OpenSimplex2 | |
*/ | |
public class OpenSimplex2S { | |
private static final long PRIME_X = 0x5205402B9270C86FL; | |
private static final long PRIME_Y = 0x598CD327003817B5L; | |
private static final long PRIME_Z = 0x5BCC226E9FA0BACBL; | |
private static final long PRIME_W = 0x56CC5227E58F554BL; | |
private static final long HASH_MULTIPLIER = 0x53A3F72DEEC546F5L; | |
private static final long SEED_FLIP_3D = -0x52D547B2E96ED629L; | |
private static final double ROOT2OVER2 = 0.7071067811865476; | |
private static final double SKEW_2D = 0.366025403784439; | |
private static final double UNSKEW_2D = -0.21132486540518713; | |
private static final double ROOT3OVER3 = 0.577350269189626; | |
private static final double FALLBACK_ROTATE3 = 2.0 / 3.0; | |
private static final double ROTATE3_ORTHOGONALIZER = UNSKEW_2D; | |
private static final float SKEW_4D = 0.309016994374947f; | |
private static final float UNSKEW_4D = -0.138196601125011f; | |
private static final int N_GRADS_2D_EXPONENT = 7; | |
private static final int N_GRADS_3D_EXPONENT = 8; | |
private static final int N_GRADS_4D_EXPONENT = 9; | |
private static final int N_GRADS_2D = 1 << N_GRADS_2D_EXPONENT; | |
private static final int N_GRADS_3D = 1 << N_GRADS_3D_EXPONENT; | |
private static final int N_GRADS_4D = 1 << N_GRADS_4D_EXPONENT; | |
private static final double NORMALIZER_2D = 0.05481866495625118; | |
private static final double NORMALIZER_3D = 0.2781926117527186; | |
private static final double NORMALIZER_4D = 0.11127401889945551; | |
private static final float RSQUARED_2D = 2.0f / 3.0f; | |
private static final float RSQUARED_3D = 3.0f / 4.0f; | |
private static final float RSQUARED_4D = 4.0f / 5.0f; | |
/* | |
* Noise Evaluators | |
*/ | |
/** | |
* 2D OpenSimplex2S/SuperSimplex noise, standard lattice orientation. | |
*/ | |
public static float noise2(long seed, double x, double y) { | |
// Get points for A2* lattice | |
double s = SKEW_2D * (x + y); | |
double xs = x + s, ys = y + s; | |
return noise2_UnskewedBase(seed, xs, ys); | |
} | |
/** | |
* 2D OpenSimplex2S/SuperSimplex noise, with Y pointing down the main diagonal. | |
* Might be better for a 2D sandbox style game, where Y is vertical. | |
* Probably slightly less optimal for heightmaps or continent maps, | |
* unless your map is centered around an equator. It's a slight | |
* difference, but the option is here to make it easy. | |
*/ | |
public static float noise2_ImproveX(long seed, double x, double y) { | |
// Skew transform and rotation baked into one. | |
double xx = x * ROOT2OVER2; | |
double yy = y * (ROOT2OVER2 * (1 + 2 * SKEW_2D)); | |
return noise2_UnskewedBase(seed, yy + xx, yy - xx); | |
} | |
/** | |
* 2D OpenSimplex2S/SuperSimplex noise base. | |
*/ | |
private static float noise2_UnskewedBase(long seed, double xs, double ys) { | |
// Get base points and offsets. | |
int xsb = fastFloor(xs), ysb = fastFloor(ys); | |
float xi = (float)(xs - xsb), yi = (float)(ys - ysb); | |
// Prime pre-multiplication for hash. | |
long xsbp = xsb * PRIME_X, ysbp = ysb * PRIME_Y; | |
// Unskew. | |
float t = (xi + yi) * (float)UNSKEW_2D; | |
float dx0 = xi + t, dy0 = yi + t; | |
// First vertex. | |
float a0 = RSQUARED_2D - dx0 * dx0 - dy0 * dy0; | |
float value = (a0 * a0) * (a0 * a0) * grad(seed, xsbp, ysbp, dx0, dy0); | |
// Second vertex. | |
float a1 = (float)(2 * (1 + 2 * UNSKEW_2D) * (1 / UNSKEW_2D + 2)) * t + ((float)(-2 * (1 + 2 * UNSKEW_2D) * (1 + 2 * UNSKEW_2D)) + a0); | |
float dx1 = dx0 - (float)(1 + 2 * UNSKEW_2D); | |
float dy1 = dy0 - (float)(1 + 2 * UNSKEW_2D); | |
value += (a1 * a1) * (a1 * a1) * grad(seed, xsbp + PRIME_X, ysbp + PRIME_Y, dx1, dy1); | |
// Third and fourth vertices. | |
// Nested conditionals were faster than compact bit logic/arithmetic. | |
float xmyi = xi - yi; | |
if (t < UNSKEW_2D) { | |
if (xi + xmyi > 1) { | |
float dx2 = dx0 - (float)(3 * UNSKEW_2D + 2); | |
float dy2 = dy0 - (float)(3 * UNSKEW_2D + 1); | |
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; | |
if (a2 > 0) { | |
value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp + (PRIME_X << 1), ysbp + PRIME_Y, dx2, dy2); | |
} | |
} | |
else | |
{ | |
float dx2 = dx0 - (float)UNSKEW_2D; | |
float dy2 = dy0 - (float)(UNSKEW_2D + 1); | |
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; | |
if (a2 > 0) { | |
value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2); | |
} | |
} | |
if (yi - xmyi > 1) { | |
float dx3 = dx0 - (float)(3 * UNSKEW_2D + 1); | |
float dy3 = dy0 - (float)(3 * UNSKEW_2D + 2); | |
float a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3; | |
if (a3 > 0) { | |
value += (a3 * a3) * (a3 * a3) * grad(seed, xsbp + PRIME_X, ysbp + (PRIME_Y << 1), dx3, dy3); | |
} | |
} | |
else | |
{ | |
float dx3 = dx0 - (float)(UNSKEW_2D + 1); | |
float dy3 = dy0 - (float)UNSKEW_2D; | |
float a3 = RSQUARED_2D - dx3 * dx3 - dy3 * dy3; | |
if (a3 > 0) { | |
value += (a3 * a3) * (a3 * a3) * grad(seed, xsbp + PRIME_X, ysbp, dx3, dy3); | |
} | |
} | |
} | |
else | |
{ | |
if (xi + xmyi < 0) { | |
float dx2 = dx0 + (float)(1 + UNSKEW_2D); | |
float dy2 = dy0 + (float)UNSKEW_2D; | |
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; | |
if (a2 > 0) { | |
value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp - PRIME_X, ysbp, dx2, dy2); | |
} | |
} | |
else | |
{ | |
float dx2 = dx0 - (float)(UNSKEW_2D + 1); | |
float dy2 = dy0 - (float)UNSKEW_2D; | |
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; | |
if (a2 > 0) { | |
value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp + PRIME_X, ysbp, dx2, dy2); | |
} | |
} | |
if (yi < xmyi) { | |
float dx2 = dx0 + (float)UNSKEW_2D; | |
float dy2 = dy0 + (float)(UNSKEW_2D + 1); | |
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; | |
if (a2 > 0) { | |
value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp, ysbp - PRIME_Y, dx2, dy2); | |
} | |
} | |
else | |
{ | |
float dx2 = dx0 - (float)UNSKEW_2D; | |
float dy2 = dy0 - (float)(UNSKEW_2D + 1); | |
float a2 = RSQUARED_2D - dx2 * dx2 - dy2 * dy2; | |
if (a2 > 0) { | |
value += (a2 * a2) * (a2 * a2) * grad(seed, xsbp, ysbp + PRIME_Y, dx2, dy2); | |
} | |
} | |
} | |
return value; | |
} | |
/** | |
* 3D OpenSimplex2S/SuperSimplex noise, with better visual isotropy in (X, Y). | |
* Recommended for 3D terrain and time-varied animations. | |
* The Z coordinate should always be the "different" coordinate in whatever your use case is. | |
* If Y is vertical in world coordinates, call noise3_ImproveXZ(x, z, Y) or use noise3_XZBeforeY. | |
* If Z is vertical in world coordinates, call noise3_ImproveXZ(x, y, Z). | |
* For a time varied animation, call noise3_ImproveXY(x, y, T). | |
*/ | |
public static float noise3_ImproveXY(long seed, double x, double y, double z) { | |
// Re-orient the cubic lattices without skewing, so Z points up the main lattice diagonal, | |
// and the planes formed by XY are moved far out of alignment with the cube faces. | |
// Orthonormal rotation. Not a skew transform. | |
double xy = x + y; | |
double s2 = xy * ROTATE3_ORTHOGONALIZER; | |
double zz = z * ROOT3OVER3; | |
double xr = x + s2 + zz; | |
double yr = y + s2 + zz; | |
double zr = xy * -ROOT3OVER3 + zz; | |
// Evaluate both lattices to form a BCC lattice. | |
return noise3_UnrotatedBase(seed, xr, yr, zr); | |
} | |
/** | |
* 3D OpenSimplex2S/SuperSimplex noise, with better visual isotropy in (X, Z). | |
* Recommended for 3D terrain and time-varied animations. | |
* The Y coordinate should always be the "different" coordinate in whatever your use case is. | |
* If Y is vertical in world coordinates, call noise3_ImproveXZ(x, Y, z). | |
* If Z is vertical in world coordinates, call noise3_ImproveXZ(x, Z, y) or use noise3_ImproveXY. | |
* For a time varied animation, call noise3_ImproveXZ(x, T, y) or use noise3_ImproveXY. | |
*/ | |
public static float noise3_ImproveXZ(long seed, double x, double y, double z) { | |
// Re-orient the cubic lattices without skewing, so Y points up the main lattice diagonal, | |
// and the planes formed by XZ are moved far out of alignment with the cube faces. | |
// Orthonormal rotation. Not a skew transform. | |
double xz = x + z; | |
double s2 = xz * -0.211324865405187; | |
double yy = y * ROOT3OVER3; | |
double xr = x + s2 + yy; | |
double zr = z + s2 + yy; | |
double yr = xz * -ROOT3OVER3 + yy; | |
// Evaluate both lattices to form a BCC lattice. | |
return noise3_UnrotatedBase(seed, xr, yr, zr); | |
} | |
/** | |
* 3D OpenSimplex2S/SuperSimplex noise, fallback rotation option | |
* Use noise3_ImproveXY or noise3_ImproveXZ instead, wherever appropriate. | |
* They have less diagonal bias. This function's best use is as a fallback. | |
*/ | |
public static float noise3_Fallback(long seed, double x, double y, double z) { | |
// Re-orient the cubic lattices via rotation, to produce a familiar look. | |
// Orthonormal rotation. Not a skew transform. | |
double r = FALLBACK_ROTATE3 * (x + y + z); | |
double xr = r - x, yr = r - y, zr = r - z; | |
// Evaluate both lattices to form a BCC lattice. | |
return noise3_UnrotatedBase(seed, xr, yr, zr); | |
} | |
/** | |
* Generate overlapping cubic lattices for 3D Re-oriented BCC noise. | |
* Lookup table implementation inspired by DigitalShadow. | |
* It was actually faster to narrow down the points in the loop itself, | |
* than to build up the index with enough info to isolate 8 points. | |
*/ | |
private static float noise3_UnrotatedBase(long seed, double xr, double yr, double zr) { | |
// Get base points and offsets. | |
int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr); | |
float xi = (float)(xr - xrb), yi = (float)(yr - yrb), zi = (float)(zr - zrb); | |
// Prime pre-multiplication for hash. Also flip seed for second lattice copy. | |
long xrbp = xrb * PRIME_X, yrbp = yrb * PRIME_Y, zrbp = zrb * PRIME_Z; | |
long seed2 = seed ^ -0x52D547B2E96ED629L; | |
// -1 if positive, 0 if negative. | |
int xNMask = (int)(-0.5f - xi), yNMask = (int)(-0.5f - yi), zNMask = (int)(-0.5f - zi); | |
// First vertex. | |
float x0 = xi + xNMask; | |
float y0 = yi + yNMask; | |
float z0 = zi + zNMask; | |
float a0 = RSQUARED_3D - x0 * x0 - y0 * y0 - z0 * z0; | |
float value = (a0 * a0) * (a0 * a0) * grad(seed, | |
xrbp + (xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), x0, y0, z0); | |
// Second vertex. | |
float x1 = xi - 0.5f; | |
float y1 = yi - 0.5f; | |
float z1 = zi - 0.5f; | |
float a1 = RSQUARED_3D - x1 * x1 - y1 * y1 - z1 * z1; | |
value += (a1 * a1) * (a1 * a1) * grad(seed2, | |
xrbp + PRIME_X, yrbp + PRIME_Y, zrbp + PRIME_Z, x1, y1, z1); | |
// Shortcuts for building the remaining falloffs. | |
// Derived by subtracting the polynomials with the offsets plugged in. | |
float xAFlipMask0 = ((xNMask | 1) << 1) * x1; | |
float yAFlipMask0 = ((yNMask | 1) << 1) * y1; | |
float zAFlipMask0 = ((zNMask | 1) << 1) * z1; | |
float xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0f; | |
float yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0f; | |
float zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0f; | |
boolean skip5 = false; | |
float a2 = xAFlipMask0 + a0; | |
if (a2 > 0) { | |
float x2 = x0 - (xNMask | 1); | |
float y2 = y0; | |
float z2 = z0; | |
value += (a2 * a2) * (a2 * a2) * grad(seed, | |
xrbp + (~xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), x2, y2, z2); | |
} | |
else | |
{ | |
float a3 = yAFlipMask0 + zAFlipMask0 + a0; | |
if (a3 > 0) { | |
float x3 = x0; | |
float y3 = y0 - (yNMask | 1); | |
float z3 = z0 - (zNMask | 1); | |
value += (a3 * a3) * (a3 * a3) * grad(seed, | |
xrbp + (xNMask & PRIME_X), yrbp + (~yNMask & PRIME_Y), zrbp + (~zNMask & PRIME_Z), x3, y3, z3); | |
} | |
float a4 = xAFlipMask1 + a1; | |
if (a4 > 0) { | |
float x4 = (xNMask | 1) + x1; | |
float y4 = y1; | |
float z4 = z1; | |
value += (a4 * a4) * (a4 * a4) * grad(seed2, | |
xrbp + (xNMask & (PRIME_X * 2)), yrbp + PRIME_Y, zrbp + PRIME_Z, x4, y4, z4); | |
skip5 = true; | |
} | |
} | |
boolean skip9 = false; | |
float a6 = yAFlipMask0 + a0; | |
if (a6 > 0) { | |
float x6 = x0; | |
float y6 = y0 - (yNMask | 1); | |
float z6 = z0; | |
value += (a6 * a6) * (a6 * a6) * grad(seed, | |
xrbp + (xNMask & PRIME_X), yrbp + (~yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), x6, y6, z6); | |
} | |
else | |
{ | |
float a7 = xAFlipMask0 + zAFlipMask0 + a0; | |
if (a7 > 0) { | |
float x7 = x0 - (xNMask | 1); | |
float y7 = y0; | |
float z7 = z0 - (zNMask | 1); | |
value += (a7 * a7) * (a7 * a7) * grad(seed, | |
xrbp + (~xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (~zNMask & PRIME_Z), x7, y7, z7); | |
} | |
float a8 = yAFlipMask1 + a1; | |
if (a8 > 0) { | |
float x8 = x1; | |
float y8 = (yNMask | 1) + y1; | |
float z8 = z1; | |
value += (a8 * a8) * (a8 * a8) * grad(seed2, | |
xrbp + PRIME_X, yrbp + (yNMask & (PRIME_Y << 1)), zrbp + PRIME_Z, x8, y8, z8); | |
skip9 = true; | |
} | |
} | |
boolean skipD = false; | |
float aA = zAFlipMask0 + a0; | |
if (aA > 0) { | |
float xA = x0; | |
float yA = y0; | |
float zA = z0 - (zNMask | 1); | |
value += (aA * aA) * (aA * aA) * grad(seed, | |
xrbp + (xNMask & PRIME_X), yrbp + (yNMask & PRIME_Y), zrbp + (~zNMask & PRIME_Z), xA, yA, zA); | |
} | |
else | |
{ | |
float aB = xAFlipMask0 + yAFlipMask0 + a0; | |
if (aB > 0) { | |
float xB = x0 - (xNMask | 1); | |
float yB = y0 - (yNMask | 1); | |
float zB = z0; | |
value += (aB * aB) * (aB * aB) * grad(seed, | |
xrbp + (~xNMask & PRIME_X), yrbp + (~yNMask & PRIME_Y), zrbp + (zNMask & PRIME_Z), xB, yB, zB); | |
} | |
float aC = zAFlipMask1 + a1; | |
if (aC > 0) { | |
float xC = x1; | |
float yC = y1; | |
float zC = (zNMask | 1) + z1; | |
value += (aC * aC) * (aC * aC) * grad(seed2, | |
xrbp + PRIME_X, yrbp + PRIME_Y, zrbp + (zNMask & (PRIME_Z << 1)), xC, yC, zC); | |
skipD = true; | |
} | |
} | |
if (!skip5) { | |
float a5 = yAFlipMask1 + zAFlipMask1 + a1; | |
if (a5 > 0) { | |
float x5 = x1; | |
float y5 = (yNMask | 1) + y1; | |
float z5 = (zNMask | 1) + z1; | |
value += (a5 * a5) * (a5 * a5) * grad(seed2, | |
xrbp + PRIME_X, yrbp + (yNMask & (PRIME_Y << 1)), zrbp + (zNMask & (PRIME_Z << 1)), x5, y5, z5); | |
} | |
} | |
if (!skip9) { | |
float a9 = xAFlipMask1 + zAFlipMask1 + a1; | |
if (a9 > 0) { | |
float x9 = (xNMask | 1) + x1; | |
float y9 = y1; | |
float z9 = (zNMask | 1) + z1; | |
value += (a9 * a9) * (a9 * a9) * grad(seed2, | |
xrbp + (xNMask & (PRIME_X * 2)), yrbp + PRIME_Y, zrbp + (zNMask & (PRIME_Z << 1)), x9, y9, z9); | |
} | |
} | |
if (!skipD) { | |
float aD = xAFlipMask1 + yAFlipMask1 + a1; | |
if (aD > 0) { | |
float xD = (xNMask | 1) + x1; | |
float yD = (yNMask | 1) + y1; | |
float zD = z1; | |
value += (aD * aD) * (aD * aD) * grad(seed2, | |
xrbp + (xNMask & (PRIME_X << 1)), yrbp + (yNMask & (PRIME_Y << 1)), zrbp + PRIME_Z, xD, yD, zD); | |
} | |
} | |
return value; | |
} | |
/** | |
* 4D SuperSimplex noise, with XYZ oriented like noise3_ImproveXY | |
* and W for an extra degree of freedom. W repeats eventually. | |
* Recommended for time-varied animations which texture a 3D object (W=time) | |
* in a space where Z is vertical | |
*/ | |
public static float noise4_ImproveXYZ_ImproveXY(long seed, double x, double y, double z, double w) { | |
double xy = x + y; | |
double s2 = xy * -0.21132486540518699998; | |
double zz = z * 0.28867513459481294226; | |
double ww = w * 1.118033988749894; | |
double xr = x + (zz + ww + s2), yr = y + (zz + ww + s2); | |
double zr = xy * -0.57735026918962599998 + (zz + ww); | |
double wr = z * -0.866025403784439 + ww; | |
return noise4_UnskewedBase(seed, xr, yr, zr, wr); | |
} | |
/** | |
* 4D SuperSimplex noise, with XYZ oriented like noise3_ImproveXZ | |
* and W for an extra degree of freedom. W repeats eventually. | |
* Recommended for time-varied animations which texture a 3D object (W=time) | |
* in a space where Y is vertical | |
*/ | |
public static float noise4_ImproveXYZ_ImproveXZ(long seed, double x, double y, double z, double w) { | |
double xz = x + z; | |
double s2 = xz * -0.21132486540518699998; | |
double yy = y * 0.28867513459481294226; | |
double ww = w * 1.118033988749894; | |
double xr = x + (yy + ww + s2), zr = z + (yy + ww + s2); | |
double yr = xz * -0.57735026918962599998 + (yy + ww); | |
double wr = y * -0.866025403784439 + ww; | |
return noise4_UnskewedBase(seed, xr, yr, zr, wr); | |
} | |
/** | |
* 4D SuperSimplex noise, with XYZ oriented like noise3_Fallback | |
* and W for an extra degree of freedom. W repeats eventually. | |
* Recommended for time-varied animations which texture a 3D object (W=time) | |
* where there isn't a clear distinction between horizontal and vertical | |
*/ | |
public static float noise4_ImproveXYZ(long seed, double x, double y, double z, double w) { | |
double xyz = x + y + z; | |
double ww = w * 1.118033988749894; | |
double s2 = xyz * -0.16666666666666666 + ww; | |
double xs = x + s2, ys = y + s2, zs = z + s2, ws = -0.5 * xyz + ww; | |
return noise4_UnskewedBase(seed, xs, ys, zs, ws); | |
} | |
/** | |
* 4D SuperSimplex noise, with XY and ZW forming orthogonal triangular-based planes. | |
* Recommended for 3D terrain, where X and Y (or Z and W) are horizontal. | |
* Recommended for noise(x, y, sin(time), cos(time)) trick. | |
*/ | |
public static float noise4_ImproveXY_ImproveZW(long seed, double x, double y, double z, double w) { | |
double s2 = (x + y) * -0.28522513987434876941 + (z + w) * 0.83897065470611435718; | |
double t2 = (z + w) * 0.21939749883706435719 + (x + y) * -0.48214856493302476942; | |
double xs = x + s2, ys = y + s2, zs = z + t2, ws = w + t2; | |
return noise4_UnskewedBase(seed, xs, ys, zs, ws); | |
} | |
/** | |
* 4D SuperSimplex noise, fallback lattice orientation. | |
*/ | |
public static float noise4_Fallback(long seed, double x, double y, double z, double w) { | |
// Get points for A4 lattice | |
double s = SKEW_4D * (x + y + z + w); | |
double xs = x + s, ys = y + s, zs = z + s, ws = w + s; | |
return noise4_UnskewedBase(seed, xs, ys, zs, ws); | |
} | |
/** | |
* 4D SuperSimplex noise base. | |
* Using ultra-simple 4x4x4x4 lookup partitioning. | |
* This isn't as elegant or SIMD/GPU/etc. portable as other approaches, | |
* but it competes performance-wise with optimized 2014 OpenSimplex. | |
*/ | |
private static float noise4_UnskewedBase(long seed, double xs, double ys, double zs, double ws) { | |
// Get base points and offsets | |
int xsb = fastFloor(xs), ysb = fastFloor(ys), zsb = fastFloor(zs), wsb = fastFloor(ws); | |
float xsi = (float)(xs - xsb), ysi = (float)(ys - ysb), zsi = (float)(zs - zsb), wsi = (float)(ws - wsb); | |
// Unskewed offsets | |
float ssi = (xsi + ysi + zsi + wsi) * UNSKEW_4D; | |
float xi = xsi + ssi, yi = ysi + ssi, zi = zsi + ssi, wi = wsi + ssi; | |
// Prime pre-multiplication for hash. | |
long xsvp = xsb * PRIME_X, ysvp = ysb * PRIME_Y, zsvp = zsb * PRIME_Z, wsvp = wsb * PRIME_W; | |
// Index into initial table. | |
int index = ((fastFloor(xs * 4) & 3) << 0) | |
| ((fastFloor(ys * 4) & 3) << 2) | |
| ((fastFloor(zs * 4) & 3) << 4) | |
| ((fastFloor(ws * 4) & 3) << 6); | |
// Point contributions | |
float value = 0; | |
int secondaryIndexStartAndStop = LOOKUP_4D_A[index]; | |
int secondaryIndexStart = secondaryIndexStartAndStop & 0xFFFF; | |
int secondaryIndexStop = secondaryIndexStartAndStop >> 16; | |
for (int i = secondaryIndexStart; i < secondaryIndexStop; i++) { | |
LatticeVertex4D c = LOOKUP_4D_B[i]; | |
float dx = xi + c.dx, dy = yi + c.dy, dz = zi + c.dz, dw = wi + c.dw; | |
float a = (dx * dx + dy * dy) + (dz * dz + dw * dw); | |
if (a < RSQUARED_4D) { | |
a -= RSQUARED_4D; | |
a *= a; | |
value += a * a * grad(seed, xsvp + c.xsvp, ysvp + c.ysvp, zsvp + c.zsvp, wsvp + c.wsvp, dx, dy, dz, dw); | |
} | |
} | |
return value; | |
} | |
/* | |
* Utility | |
*/ | |
private static float grad(long seed, long xsvp, long ysvp, float dx, float dy) { | |
long hash = seed ^ xsvp ^ ysvp; | |
hash *= HASH_MULTIPLIER; | |
hash ^= hash >> (64 - N_GRADS_2D_EXPONENT + 1); | |
int gi = (int)hash & ((N_GRADS_2D - 1) << 1); | |
return GRADIENTS_2D[gi | 0] * dx + GRADIENTS_2D[gi | 1] * dy; | |
} | |
private static float grad(long seed, long xrvp, long yrvp, long zrvp, float dx, float dy, float dz) { | |
long hash = (seed ^ xrvp) ^ (yrvp ^ zrvp); | |
hash *= HASH_MULTIPLIER; | |
hash ^= hash >> (64 - N_GRADS_3D_EXPONENT + 2); | |
int gi = (int)hash & ((N_GRADS_3D - 1) << 2); | |
return GRADIENTS_3D[gi | 0] * dx + GRADIENTS_3D[gi | 1] * dy + GRADIENTS_3D[gi | 2] * dz; | |
} | |
private static float grad(long seed, long xsvp, long ysvp, long zsvp, long wsvp, float dx, float dy, float dz, float dw) { | |
long hash = seed ^ (xsvp ^ ysvp) ^ (zsvp ^ wsvp); | |
hash *= HASH_MULTIPLIER; | |
hash ^= hash >> (64 - N_GRADS_4D_EXPONENT + 2); | |
int gi = (int)hash & ((N_GRADS_4D - 1) << 2); | |
return (GRADIENTS_4D[gi | 0] * dx + GRADIENTS_4D[gi | 1] * dy) + (GRADIENTS_4D[gi | 2] * dz + GRADIENTS_4D[gi | 3] * dw); | |
} | |
private static int fastFloor(double x) { | |
int xi = (int)x; | |
return x < xi ? xi - 1 : xi; | |
} | |
/* | |
* Lookup Tables & Gradients | |
*/ | |
private static float[] GRADIENTS_2D; | |
private static float[] GRADIENTS_3D; | |
private static float[] GRADIENTS_4D; | |
private static int[] LOOKUP_4D_A; | |
private static LatticeVertex4D[] LOOKUP_4D_B; | |
static { | |
GRADIENTS_2D = new float[N_GRADS_2D * 2]; | |
float[] grad2 = { | |
0.38268343236509f, 0.923879532511287f, | |
0.923879532511287f, 0.38268343236509f, | |
0.923879532511287f, -0.38268343236509f, | |
0.38268343236509f, -0.923879532511287f, | |
-0.38268343236509f, -0.923879532511287f, | |
-0.923879532511287f, -0.38268343236509f, | |
-0.923879532511287f, 0.38268343236509f, | |
-0.38268343236509f, 0.923879532511287f, | |
//-------------------------------------// | |
0.130526192220052f, 0.99144486137381f, | |
0.608761429008721f, 0.793353340291235f, | |
0.793353340291235f, 0.608761429008721f, | |
0.99144486137381f, 0.130526192220051f, | |
0.99144486137381f, -0.130526192220051f, | |
0.793353340291235f, -0.60876142900872f, | |
0.608761429008721f, -0.793353340291235f, | |
0.130526192220052f, -0.99144486137381f, | |
-0.130526192220052f, -0.99144486137381f, | |
-0.608761429008721f, -0.793353340291235f, | |
-0.793353340291235f, -0.608761429008721f, | |
-0.99144486137381f, -0.130526192220052f, | |
-0.99144486137381f, 0.130526192220051f, | |
-0.793353340291235f, 0.608761429008721f, | |
-0.608761429008721f, 0.793353340291235f, | |
-0.130526192220052f, 0.99144486137381f, | |
}; | |
for (int i = 0; i < grad2.length; i++) { | |
grad2[i] = (float)(grad2[i] / NORMALIZER_2D); | |
} | |
for (int i = 0, j = 0; i < GRADIENTS_2D.length; i++, j++) { | |
if (j == grad2.length) j = 0; | |
GRADIENTS_2D[i] = grad2[j]; | |
} | |
GRADIENTS_3D = new float[N_GRADS_3D * 4]; | |
float[] grad3 = { | |
2.22474487139f, 2.22474487139f, -1.0f, 0.0f, | |
2.22474487139f, 2.22474487139f, 1.0f, 0.0f, | |
3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, | |
1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, | |
-2.22474487139f, 2.22474487139f, -1.0f, 0.0f, | |
-2.22474487139f, 2.22474487139f, 1.0f, 0.0f, | |
-1.1721513422464978f, 3.0862664687972017f, 0.0f, 0.0f, | |
-3.0862664687972017f, 1.1721513422464978f, 0.0f, 0.0f, | |
-1.0f, -2.22474487139f, -2.22474487139f, 0.0f, | |
1.0f, -2.22474487139f, -2.22474487139f, 0.0f, | |
0.0f, -3.0862664687972017f, -1.1721513422464978f, 0.0f, | |
0.0f, -1.1721513422464978f, -3.0862664687972017f, 0.0f, | |
-1.0f, -2.22474487139f, 2.22474487139f, 0.0f, | |
1.0f, -2.22474487139f, 2.22474487139f, 0.0f, | |
0.0f, -1.1721513422464978f, 3.0862664687972017f, 0.0f, | |
0.0f, -3.0862664687972017f, 1.1721513422464978f, 0.0f, | |
//--------------------------------------------------------------------// | |
-2.22474487139f, -2.22474487139f, -1.0f, 0.0f, | |
-2.22474487139f, -2.22474487139f, 1.0f, 0.0f, | |
-3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, | |
-1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, | |
-2.22474487139f, -1.0f, -2.22474487139f, 0.0f, | |
-2.22474487139f, 1.0f, -2.22474487139f, 0.0f, | |
-1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, | |
-3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, | |
-2.22474487139f, -1.0f, 2.22474487139f, 0.0f, | |
-2.22474487139f, 1.0f, 2.22474487139f, 0.0f, | |
-3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, | |
-1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, | |
-1.0f, 2.22474487139f, -2.22474487139f, 0.0f, | |
1.0f, 2.22474487139f, -2.22474487139f, 0.0f, | |
0.0f, 1.1721513422464978f, -3.0862664687972017f, 0.0f, | |
0.0f, 3.0862664687972017f, -1.1721513422464978f, 0.0f, | |
-1.0f, 2.22474487139f, 2.22474487139f, 0.0f, | |
1.0f, 2.22474487139f, 2.22474487139f, 0.0f, | |
0.0f, 3.0862664687972017f, 1.1721513422464978f, 0.0f, | |
0.0f, 1.1721513422464978f, 3.0862664687972017f, 0.0f, | |
2.22474487139f, -2.22474487139f, -1.0f, 0.0f, | |
2.22474487139f, -2.22474487139f, 1.0f, 0.0f, | |
1.1721513422464978f, -3.0862664687972017f, 0.0f, 0.0f, | |
3.0862664687972017f, -1.1721513422464978f, 0.0f, 0.0f, | |
2.22474487139f, -1.0f, -2.22474487139f, 0.0f, | |
2.22474487139f, 1.0f, -2.22474487139f, 0.0f, | |
3.0862664687972017f, 0.0f, -1.1721513422464978f, 0.0f, | |
1.1721513422464978f, 0.0f, -3.0862664687972017f, 0.0f, | |
2.22474487139f, -1.0f, 2.22474487139f, 0.0f, | |
2.22474487139f, 1.0f, 2.22474487139f, 0.0f, | |
1.1721513422464978f, 0.0f, 3.0862664687972017f, 0.0f, | |
3.0862664687972017f, 0.0f, 1.1721513422464978f, 0.0f, | |
}; | |
for (int i = 0; i < grad3.length; i++) { | |
grad3[i] = (float)(grad3[i] / NORMALIZER_3D); | |
} | |
for (int i = 0, j = 0; i < GRADIENTS_3D.length; i++, j++) { | |
if (j == grad3.length) j = 0; | |
GRADIENTS_3D[i] = grad3[j]; | |
} | |
GRADIENTS_4D = new float[N_GRADS_4D * 4]; | |
float[] grad4 = { | |
-0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, | |
-0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, | |
-0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, | |
-0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, | |
-0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, | |
-0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, | |
-0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, | |
-0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, | |
-0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, | |
-0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, | |
-0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, | |
-0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, | |
-0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, | |
-0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, | |
-0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, | |
-0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, | |
-0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, | |
-0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, | |
-0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, | |
-0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, | |
-0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, | |
-0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, | |
-0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, | |
-0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, | |
0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, -0.3239847771997537f, | |
0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, 0.15296486218853164f, | |
0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, -0.4004672082940195f, | |
0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, 0.08164729285680945f, | |
0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, -0.08164729285680945f, | |
0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, 0.4004672082940195f, | |
0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, -0.15296486218853164f, | |
0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, 0.3239847771997537f, | |
//------------------------------------------------------------------------------------------// | |
-0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, | |
-0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, | |
-0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, | |
-0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, | |
-0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, | |
-0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, | |
-0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, | |
-0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, | |
-0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, -0.37968289875261624f, | |
-0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, 0.12128480194602098f, | |
-0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, -0.4321472685365301f, | |
0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, -0.4321472685365301f, | |
-0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, 0.044802370851755174f, | |
0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, 0.044802370851755174f, | |
0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, -0.508629699630796f, | |
-0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, -0.03381941603233842f, | |
-0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, -0.37968289875261624f, | |
-0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, 0.12128480194602098f, | |
-0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, -0.4321472685365301f, | |
0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, -0.4321472685365301f, | |
-0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, 0.044802370851755174f, | |
0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, 0.044802370851755174f, | |
0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, -0.508629699630796f, | |
-0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, -0.03381941603233842f, | |
-0.37968289875261624f, -0.37968289875261624f, -0.37968289875261624f, -0.753341017856078f, | |
-0.4321472685365301f, -0.4321472685365301f, 0.12128480194602098f, -0.7821684431180708f, | |
-0.4321472685365301f, 0.12128480194602098f, -0.4321472685365301f, -0.7821684431180708f, | |
0.12128480194602098f, -0.4321472685365301f, -0.4321472685365301f, -0.7821684431180708f, | |
-0.508629699630796f, 0.044802370851755174f, 0.044802370851755174f, -0.8586508742123365f, | |
0.044802370851755174f, -0.508629699630796f, 0.044802370851755174f, -0.8586508742123365f, | |
0.044802370851755174f, 0.044802370851755174f, -0.508629699630796f, -0.8586508742123365f, | |
-0.03381941603233842f, -0.03381941603233842f, -0.03381941603233842f, -0.9982828964265062f, | |
-0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, 0.5794684678643381f, | |
-0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, 0.5029860367700724f, | |
0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, 0.5029860367700724f, | |
0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, 0.4553054119602712f, | |
-0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, 0.8828161875373585f, | |
-0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, 0.7504883828755602f, | |
0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, 0.7504883828755602f, | |
0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, 0.6740059517812944f, | |
-0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, | |
-0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, | |
0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, | |
0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, | |
-0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, | |
-0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, | |
0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, | |
0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, | |
-0.3239847771997537f, -0.6740059517812944f, 0.5794684678643381f, -0.3239847771997537f, | |
-0.4004672082940195f, -0.7504883828755602f, 0.5029860367700724f, 0.15296486218853164f, | |
0.15296486218853164f, -0.7504883828755602f, 0.5029860367700724f, -0.4004672082940195f, | |
0.08164729285680945f, -0.8828161875373585f, 0.4553054119602712f, 0.08164729285680945f, | |
-0.08164729285680945f, -0.4553054119602712f, 0.8828161875373585f, -0.08164729285680945f, | |
-0.15296486218853164f, -0.5029860367700724f, 0.7504883828755602f, 0.4004672082940195f, | |
0.4004672082940195f, -0.5029860367700724f, 0.7504883828755602f, -0.15296486218853164f, | |
0.3239847771997537f, -0.5794684678643381f, 0.6740059517812944f, 0.3239847771997537f, | |
-0.3239847771997537f, -0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, | |
-0.4004672082940195f, 0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, | |
0.15296486218853164f, -0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, | |
0.08164729285680945f, 0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, | |
-0.08164729285680945f, -0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, | |
-0.15296486218853164f, 0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, | |
0.4004672082940195f, -0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, | |
0.3239847771997537f, 0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, | |
-0.3239847771997537f, 0.5794684678643381f, -0.6740059517812944f, -0.3239847771997537f, | |
-0.4004672082940195f, 0.5029860367700724f, -0.7504883828755602f, 0.15296486218853164f, | |
0.15296486218853164f, 0.5029860367700724f, -0.7504883828755602f, -0.4004672082940195f, | |
0.08164729285680945f, 0.4553054119602712f, -0.8828161875373585f, 0.08164729285680945f, | |
-0.08164729285680945f, 0.8828161875373585f, -0.4553054119602712f, -0.08164729285680945f, | |
-0.15296486218853164f, 0.7504883828755602f, -0.5029860367700724f, 0.4004672082940195f, | |
0.4004672082940195f, 0.7504883828755602f, -0.5029860367700724f, -0.15296486218853164f, | |
0.3239847771997537f, 0.6740059517812944f, -0.5794684678643381f, 0.3239847771997537f, | |
-0.3239847771997537f, 0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, | |
-0.4004672082940195f, 0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, | |
0.15296486218853164f, 0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, | |
0.08164729285680945f, 0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, | |
-0.08164729285680945f, 0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, | |
-0.15296486218853164f, 0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, | |
0.4004672082940195f, 0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, | |
0.3239847771997537f, 0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, | |
0.5794684678643381f, -0.3239847771997537f, -0.6740059517812944f, -0.3239847771997537f, | |
0.5029860367700724f, -0.4004672082940195f, -0.7504883828755602f, 0.15296486218853164f, | |
0.5029860367700724f, 0.15296486218853164f, -0.7504883828755602f, -0.4004672082940195f, | |
0.4553054119602712f, 0.08164729285680945f, -0.8828161875373585f, 0.08164729285680945f, | |
0.8828161875373585f, -0.08164729285680945f, -0.4553054119602712f, -0.08164729285680945f, | |
0.7504883828755602f, -0.15296486218853164f, -0.5029860367700724f, 0.4004672082940195f, | |
0.7504883828755602f, 0.4004672082940195f, -0.5029860367700724f, -0.15296486218853164f, | |
0.6740059517812944f, 0.3239847771997537f, -0.5794684678643381f, 0.3239847771997537f, | |
0.5794684678643381f, -0.3239847771997537f, -0.3239847771997537f, -0.6740059517812944f, | |
0.5029860367700724f, -0.4004672082940195f, 0.15296486218853164f, -0.7504883828755602f, | |
0.5029860367700724f, 0.15296486218853164f, -0.4004672082940195f, -0.7504883828755602f, | |
0.4553054119602712f, 0.08164729285680945f, 0.08164729285680945f, -0.8828161875373585f, | |
0.8828161875373585f, -0.08164729285680945f, -0.08164729285680945f, -0.4553054119602712f, | |
0.7504883828755602f, -0.15296486218853164f, 0.4004672082940195f, -0.5029860367700724f, | |
0.7504883828755602f, 0.4004672082940195f, -0.15296486218853164f, -0.5029860367700724f, | |
0.6740059517812944f, 0.3239847771997537f, 0.3239847771997537f, -0.5794684678643381f, | |
0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, | |
-0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, | |
-0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, | |
-0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, | |
0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, 0.8586508742123365f, | |
0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, | |
0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, | |
0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, | |
0.03381941603233842f, 0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, | |
-0.044802370851755174f, 0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, | |
-0.044802370851755174f, 0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, | |
-0.12128480194602098f, 0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, | |
0.508629699630796f, -0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, | |
0.4321472685365301f, -0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, | |
0.4321472685365301f, 0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, | |
0.37968289875261624f, 0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, | |
0.03381941603233842f, 0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, | |
-0.044802370851755174f, 0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, | |
-0.044802370851755174f, 0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, | |
-0.12128480194602098f, 0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, | |
0.508629699630796f, 0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, | |
0.4321472685365301f, 0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, | |
0.4321472685365301f, 0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, | |
0.37968289875261624f, 0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, | |
0.9982828964265062f, 0.03381941603233842f, 0.03381941603233842f, 0.03381941603233842f, | |
0.8586508742123365f, -0.044802370851755174f, -0.044802370851755174f, 0.508629699630796f, | |
0.8586508742123365f, -0.044802370851755174f, 0.508629699630796f, -0.044802370851755174f, | |
0.7821684431180708f, -0.12128480194602098f, 0.4321472685365301f, 0.4321472685365301f, | |
0.8586508742123365f, 0.508629699630796f, -0.044802370851755174f, -0.044802370851755174f, | |
0.7821684431180708f, 0.4321472685365301f, -0.12128480194602098f, 0.4321472685365301f, | |
0.7821684431180708f, 0.4321472685365301f, 0.4321472685365301f, -0.12128480194602098f, | |
0.753341017856078f, 0.37968289875261624f, 0.37968289875261624f, 0.37968289875261624f, | |
}; | |
for (int i = 0; i < grad4.length; i++) { | |
grad4[i] = (float)(grad4[i] / NORMALIZER_4D); | |
} | |
for (int i = 0, j = 0; i < GRADIENTS_4D.length; i++, j++) { | |
if (j == grad4.length) j = 0; | |
GRADIENTS_4D[i] = grad4[j]; | |
} | |
int[][] lookup4DVertexCodes = { | |
new int[] { 0x15, 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, | |
new int[] { 0x01, 0x05, 0x11, 0x15, 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA }, | |
new int[] { 0x01, 0x15, 0x16, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, | |
new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, | |
new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA }, | |
new int[] { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xAA, 0xAB }, | |
new int[] { 0x04, 0x05, 0x14, 0x15, 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA }, | |
new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA }, | |
new int[] { 0x05, 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA }, | |
new int[] { 0x05, 0x15, 0x16, 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x6A, 0x9A, 0xAA, 0xAB }, | |
new int[] { 0x04, 0x15, 0x19, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xAA, 0xAE }, | |
new int[] { 0x05, 0x15, 0x19, 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x5E, 0x6A, 0x9A, 0xAA, 0xAE }, | |
new int[] { 0x05, 0x15, 0x1A, 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x5B, 0x5E, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, | |
new int[] { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, | |
new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA }, | |
new int[] { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x14, 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x6B, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xAA }, | |
new int[] { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x6B, 0x9A, 0xAA, 0xAB }, | |
new int[] { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x6E, 0x9A, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x1A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, | |
new int[] { 0x10, 0x11, 0x14, 0x15, 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA }, | |
new int[] { 0x11, 0x15, 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA }, | |
new int[] { 0x11, 0x15, 0x16, 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x67, 0x6A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA }, | |
new int[] { 0x15, 0x16, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x6B, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x14, 0x15, 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA }, | |
new int[] { 0x15, 0x16, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0xAA, 0xAB }, | |
new int[] { 0x14, 0x15, 0x19, 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x6D, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x19, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x6E, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x19, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, | |
new int[] { 0x10, 0x15, 0x25, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xAA, 0xBA }, | |
new int[] { 0x11, 0x15, 0x25, 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0x76, 0xA6, 0xAA, 0xBA }, | |
new int[] { 0x11, 0x15, 0x26, 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x67, 0x6A, 0x76, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, | |
new int[] { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x25, 0x55, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x25, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA6, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x26, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, | |
new int[] { 0x14, 0x15, 0x25, 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0x79, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x25, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x25, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x7A, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x7A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, | |
new int[] { 0x14, 0x15, 0x29, 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0x6D, 0x79, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, | |
new int[] { 0x15, 0x29, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, | |
new int[] { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6E, 0x7A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x6B, 0x6E, 0x7A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, | |
new int[] { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, | |
new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, | |
new int[] { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x44, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, | |
new int[] { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x9A, 0x9B, 0xAA, 0xAB }, | |
new int[] { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, | |
new int[] { 0x45, 0x4A, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, | |
new int[] { 0x50, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x51, 0x55, 0x56, 0x59, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x51, 0x52, 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x56, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x45, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x58, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, | |
new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, | |
new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, | |
new int[] { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA6, 0xA7, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA }, | |
new int[] { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA9, 0xAA, 0xAD, 0xAE }, | |
new int[] { 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, | |
new int[] { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x66, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x51, 0x55, 0x61, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, | |
new int[] { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x6A, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, | |
new int[] { 0x51, 0x55, 0x56, 0x62, 0x65, 0x66, 0x6A, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, | |
new int[] { 0x54, 0x55, 0x64, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, | |
new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x55, 0x56, 0x65, 0x66, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, | |
new int[] { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x6A, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, | |
new int[] { 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x15, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x68, 0x69, 0x6A, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, | |
new int[] { 0x55, 0x59, 0x65, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, | |
new int[] { 0x15, 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0xAA, 0xAB, 0xAE, 0xBA, 0xBF }, | |
new int[] { 0x40, 0x41, 0x44, 0x45, 0x50, 0x51, 0x54, 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA }, | |
new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA }, | |
new int[] { 0x41, 0x45, 0x46, 0x51, 0x52, 0x55, 0x56, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA }, | |
new int[] { 0x45, 0x46, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA }, | |
new int[] { 0x45, 0x46, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xAA, 0xAB }, | |
new int[] { 0x44, 0x45, 0x49, 0x54, 0x55, 0x58, 0x59, 0x95, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x45, 0x49, 0x55, 0x59, 0x5A, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x45, 0x49, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xAA, 0xAE }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xAF }, | |
new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA }, | |
new int[] { 0x51, 0x52, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x45, 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x45, 0x51, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA }, | |
new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA }, | |
new int[] { 0x45, 0x54, 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x58, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE }, | |
new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xAF }, | |
new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA }, | |
new int[] { 0x51, 0x52, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x51, 0x54, 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x51, 0x55, 0x56, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB }, | |
new int[] { 0x54, 0x55, 0x58, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE }, | |
new int[] { 0x54, 0x55, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAE }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x66, 0x69, 0x6A, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xAF }, | |
new int[] { 0x50, 0x51, 0x54, 0x55, 0x61, 0x64, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA }, | |
new int[] { 0x51, 0x55, 0x61, 0x65, 0x66, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA }, | |
new int[] { 0x51, 0x55, 0x56, 0x61, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xB6, 0xBA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xBB }, | |
new int[] { 0x54, 0x55, 0x64, 0x65, 0x69, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA }, | |
new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x6A, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xBB }, | |
new int[] { 0x54, 0x55, 0x59, 0x64, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xB9, 0xBA }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x55, 0x56, 0x59, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA }, | |
new int[] { 0x55, 0x56, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xBB }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xBE }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x6A, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, | |
new int[] { 0x55, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xBE }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA }, | |
new int[] { 0x40, 0x45, 0x51, 0x54, 0x55, 0x85, 0x91, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xAA, 0xEA }, | |
new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x85, 0x91, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xD6, 0xEA }, | |
new int[] { 0x41, 0x45, 0x51, 0x55, 0x56, 0x86, 0x92, 0x95, 0x96, 0x97, 0x9A, 0xA6, 0xAA, 0xAB, 0xD6, 0xEA, 0xEB }, | |
new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x45, 0x55, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xDA, 0xEA }, | |
new int[] { 0x45, 0x55, 0x56, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xDA, 0xEA }, | |
new int[] { 0x45, 0x55, 0x56, 0x86, 0x95, 0x96, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, | |
new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x85, 0x94, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xD9, 0xEA }, | |
new int[] { 0x45, 0x55, 0x59, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xDA, 0xEA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x85, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xDA, 0xEA }, | |
new int[] { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0xA6, 0xAA, 0xAB, 0xDA, 0xEA, 0xEB }, | |
new int[] { 0x44, 0x45, 0x54, 0x55, 0x59, 0x89, 0x95, 0x98, 0x99, 0x9A, 0x9D, 0xA9, 0xAA, 0xAE, 0xD9, 0xEA, 0xEE }, | |
new int[] { 0x45, 0x55, 0x59, 0x89, 0x95, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, | |
new int[] { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9E, 0xA9, 0xAA, 0xAE, 0xDA, 0xEA, 0xEE }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0x9B, 0x9E, 0xAA, 0xAB, 0xAE, 0xDA, 0xEA, 0xEF }, | |
new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0x96, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x51, 0x55, 0x91, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, | |
new int[] { 0x51, 0x55, 0x56, 0x91, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, | |
new int[] { 0x51, 0x55, 0x56, 0x92, 0x95, 0x96, 0x9A, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, | |
new int[] { 0x54, 0x55, 0x94, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, | |
new int[] { 0x55, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x55, 0x56, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x55, 0x56, 0x95, 0x96, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, | |
new int[] { 0x54, 0x55, 0x59, 0x94, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, | |
new int[] { 0x55, 0x59, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x45, 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x45, 0x55, 0x56, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, | |
new int[] { 0x54, 0x55, 0x59, 0x95, 0x98, 0x99, 0x9A, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, | |
new int[] { 0x55, 0x59, 0x95, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, | |
new int[] { 0x45, 0x55, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x95, 0x96, 0x99, 0x9A, 0xAA, 0xAB, 0xAE, 0xEA, 0xEF }, | |
new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x91, 0x94, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xE5, 0xEA }, | |
new int[] { 0x51, 0x55, 0x65, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xE6, 0xEA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x91, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xE6, 0xEA }, | |
new int[] { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xE6, 0xEA, 0xEB }, | |
new int[] { 0x54, 0x55, 0x65, 0x94, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xE9, 0xEA }, | |
new int[] { 0x55, 0x65, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x51, 0x55, 0x56, 0x66, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xAA, 0xAB, 0xEA, 0xEB }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x94, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xE9, 0xEA }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x55, 0x56, 0x59, 0x65, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xEA }, | |
new int[] { 0x55, 0x56, 0x5A, 0x66, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xEA, 0xEB }, | |
new int[] { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xE9, 0xEA, 0xEE }, | |
new int[] { 0x54, 0x55, 0x59, 0x69, 0x95, 0x99, 0x9A, 0xA5, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, | |
new int[] { 0x55, 0x59, 0x5A, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xEA, 0xEE }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xEA }, | |
new int[] { 0x50, 0x51, 0x54, 0x55, 0x65, 0x95, 0xA1, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB5, 0xBA, 0xE5, 0xEA, 0xFA }, | |
new int[] { 0x51, 0x55, 0x65, 0x95, 0xA1, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, | |
new int[] { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xB6, 0xBA, 0xE6, 0xEA, 0xFA }, | |
new int[] { 0x51, 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA7, 0xAA, 0xAB, 0xB6, 0xBA, 0xE6, 0xEA, 0xFB }, | |
new int[] { 0x54, 0x55, 0x65, 0x95, 0xA4, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, | |
new int[] { 0x55, 0x65, 0x95, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, | |
new int[] { 0x51, 0x55, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, | |
new int[] { 0x55, 0x56, 0x65, 0x66, 0x95, 0x96, 0xA5, 0xA6, 0xAA, 0xAB, 0xBA, 0xEA, 0xFB }, | |
new int[] { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xB9, 0xBA, 0xE9, 0xEA, 0xFA }, | |
new int[] { 0x54, 0x55, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, | |
new int[] { 0x55, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xBA, 0xEA, 0xFA }, | |
new int[] { 0x55, 0x56, 0x65, 0x66, 0x6A, 0x95, 0x96, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xBA, 0xEA }, | |
new int[] { 0x54, 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAD, 0xAE, 0xB9, 0xBA, 0xE9, 0xEA, 0xFE }, | |
new int[] { 0x55, 0x59, 0x65, 0x69, 0x95, 0x99, 0xA5, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA, 0xFE }, | |
new int[] { 0x55, 0x59, 0x65, 0x69, 0x6A, 0x95, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAE, 0xBA, 0xEA }, | |
new int[] { 0x55, 0x56, 0x59, 0x5A, 0x65, 0x66, 0x69, 0x6A, 0x95, 0x96, 0x99, 0x9A, 0xA5, 0xA6, 0xA9, 0xAA, 0xAB, 0xAE, 0xBA, 0xEA }, | |
}; | |
LatticeVertex4D[] latticeVerticesByCode = new LatticeVertex4D[256]; | |
for (int i = 0; i < 256; i++) { | |
int cx = ((i >> 0) & 3) - 1; | |
int cy = ((i >> 2) & 3) - 1; | |
int cz = ((i >> 4) & 3) - 1; | |
int cw = ((i >> 6) & 3) - 1; | |
latticeVerticesByCode[i] = new LatticeVertex4D(cx, cy, cz, cw); | |
} | |
int nLatticeVerticesTotal = 0; | |
for (int i = 0; i < 256; i++) { | |
nLatticeVerticesTotal += lookup4DVertexCodes[i].length; | |
} | |
LOOKUP_4D_A = new int[256]; | |
LOOKUP_4D_B = new LatticeVertex4D[nLatticeVerticesTotal]; | |
for (int i = 0, j = 0; i < 256; i++) { | |
LOOKUP_4D_A[i] = j | ((j + lookup4DVertexCodes[i].length) << 16); | |
for (int k = 0; k < lookup4DVertexCodes[i].length; k++) { | |
LOOKUP_4D_B[j++] = latticeVerticesByCode[lookup4DVertexCodes[i][k]]; | |
} | |
} | |
} | |
private static class LatticeVertex4D { | |
public final float dx, dy, dz, dw; | |
public final long xsvp, ysvp, zsvp, wsvp; | |
public LatticeVertex4D(int xsv, int ysv, int zsv, int wsv) { | |
this.xsvp = xsv * PRIME_X; this.ysvp = ysv * PRIME_Y; | |
this.zsvp = zsv * PRIME_Z; this.wsvp = wsv * PRIME_W; | |
float ssv = (xsv + ysv + zsv + wsv) * UNSKEW_4D; | |
this.dx = -xsv - ssv; | |
this.dy = -ysv - ssv; | |
this.dz = -zsv - ssv; | |
this.dw = -wsv - ssv; | |
} | |
} | |
} |
/* | |
* OpenSimplex2S Noise sample class. | |
*/ | |
import java.awt.image.BufferedImage; | |
import javax.imageio.ImageIO; | |
import java.io.*; | |
public class OpenSimplexDemo | |
{ | |
private static final long SEED = 0; | |
private static final int WIDTH = 512; | |
private static final int HEIGHT = 512; | |
private static final double FREQUENCY = 1.0 / 24.0; | |
public static void main(String[] args) | |
throws IOException { | |
BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); | |
for (int y = 0; y < HEIGHT; y++) | |
{ | |
for (int x = 0; x < WIDTH; x++) | |
{ | |
double value = OpenSimplex2S.noise3_ImproveXY(SEED, x * FREQUENCY, y * FREQUENCY, 0.0); | |
int rgb = 0x010101 * (int)((value + 1) * 127.5); | |
image.setRGB(x, y, rgb); | |
} | |
} | |
ImageIO.write(image, "png", new File("noise.png")); | |
} | |
} |
Creative Commons Legal Code | |
CC0 1.0 Universal | |
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE | |
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN | |
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS | |
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES | |
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS | |
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM | |
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED | |
HEREUNDER. | |
Statement of Purpose | |
The laws of most jurisdictions throughout the world automatically confer | |
exclusive Copyright and Related Rights (defined below) upon the creator | |
and subsequent owner(s) (each and all, an "owner") of an original work of | |
authorship and/or a database (each, a "Work"). | |
Certain owners wish to permanently relinquish those rights to a Work for | |
the purpose of contributing to a commons of creative, cultural and | |
scientific works ("Commons") that the public can reliably and without fear | |
of later claims of infringement build upon, modify, incorporate in other | |
works, reuse and redistribute as freely as possible in any form whatsoever | |
and for any purposes, including without limitation commercial purposes. | |
These owners may contribute to the Commons to promote the ideal of a free | |
culture and the further production of creative, cultural and scientific | |
works, or to gain reputation or greater distribution for their Work in | |
part through the use and efforts of others. | |
For these and/or other purposes and motivations, and without any | |
expectation of additional consideration or compensation, the person | |
associating CC0 with a Work (the "Affirmer"), to the extent that he or she | |
is an owner of Copyright and Related Rights in the Work, voluntarily | |
elects to apply CC0 to the Work and publicly distribute the Work under its | |
terms, with knowledge of his or her Copyright and Related Rights in the | |
Work and the meaning and intended legal effect of CC0 on those rights. | |
1. Copyright and Related Rights. A Work made available under CC0 may be | |
protected by copyright and related or neighboring rights ("Copyright and | |
Related Rights"). Copyright and Related Rights include, but are not | |
limited to, the following: | |
i. the right to reproduce, adapt, distribute, perform, display, | |
communicate, and translate a Work; | |
ii. moral rights retained by the original author(s) and/or performer(s); | |
iii. publicity and privacy rights pertaining to a person's image or | |
likeness depicted in a Work; | |
iv. rights protecting against unfair competition in regards to a Work, | |
subject to the limitations in paragraph 4(a), below; | |
v. rights protecting the extraction, dissemination, use and reuse of data | |
in a Work; | |
vi. database rights (such as those arising under Directive 96/9/EC of the | |
European Parliament and of the Council of 11 March 1996 on the legal | |
protection of databases, and under any national implementation | |
thereof, including any amended or successor version of such | |
directive); and | |
vii. other similar, equivalent or corresponding rights throughout the | |
world based on applicable law or treaty, and any national | |
implementations thereof. | |
2. Waiver. To the greatest extent permitted by, but not in contravention | |
of, applicable law, Affirmer hereby overtly, fully, permanently, | |
irrevocably and unconditionally waives, abandons, and surrenders all of | |
Affirmer's Copyright and Related Rights and associated claims and causes | |
of action, whether now known or unknown (including existing as well as | |
future claims and causes of action), in the Work (i) in all territories | |
worldwide, (ii) for the maximum duration provided by applicable law or | |
treaty (including future time extensions), (iii) in any current or future | |
medium and for any number of copies, and (iv) for any purpose whatsoever, | |
including without limitation commercial, advertising or promotional | |
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each | |
member of the public at large and to the detriment of Affirmer's heirs and | |
successors, fully intending that such Waiver shall not be subject to | |
revocation, rescission, cancellation, termination, or any other legal or | |
equitable action to disrupt the quiet enjoyment of the Work by the public | |
as contemplated by Affirmer's express Statement of Purpose. | |
3. Public License Fallback. Should any part of the Waiver for any reason | |
be judged legally invalid or ineffective under applicable law, then the | |
Waiver shall be preserved to the maximum extent permitted taking into | |
account Affirmer's express Statement of Purpose. In addition, to the | |
extent the Waiver is so judged Affirmer hereby grants to each affected | |
person a royalty-free, non transferable, non sublicensable, non exclusive, | |
irrevocable and unconditional license to exercise Affirmer's Copyright and | |
Related Rights in the Work (i) in all territories worldwide, (ii) for the | |
maximum duration provided by applicable law or treaty (including future | |
time extensions), (iii) in any current or future medium and for any number | |
of copies, and (iv) for any purpose whatsoever, including without | |
limitation commercial, advertising or promotional purposes (the | |
"License"). The License shall be deemed effective as of the date CC0 was | |
applied by Affirmer to the Work. Should any part of the License for any | |
reason be judged legally invalid or ineffective under applicable law, such | |
partial invalidity or ineffectiveness shall not invalidate the remainder | |
of the License, and in such case Affirmer hereby affirms that he or she | |
will not (i) exercise any of his or her remaining Copyright and Related | |
Rights in the Work or (ii) assert any associated claims and causes of | |
action with respect to the Work, in either case contrary to Affirmer's | |
express Statement of Purpose. | |
4. Limitations and Disclaimers. | |
a. No trademark or patent rights held by Affirmer are waived, abandoned, | |
surrendered, licensed or otherwise affected by this document. | |
b. Affirmer offers the Work as-is and makes no representations or | |
warranties of any kind concerning the Work, express, implied, | |
statutory or otherwise, including without limitation warranties of | |
title, merchantability, fitness for a particular purpose, non | |
infringement, or the absence of latent or other defects, accuracy, or | |
the present or absence of errors, whether or not discoverable, all to | |
the greatest extent permissible under applicable law. | |
c. Affirmer disclaims responsibility for clearing rights of other persons | |
that may apply to the Work or any use thereof, including without | |
limitation any person's Copyright and Related Rights in the Work. | |
Further, Affirmer disclaims responsibility for obtaining any necessary | |
consents, permissions or other rights required for any use of the | |
Work. | |
d. Affirmer understands and acknowledges that Creative Commons is not a | |
party to this document and has no duty or obligation with respect to | |
this CC0 or use of the Work. |
Any chance you can make periodic versions?
I would like to see a 1 dimension implementation as well.
Also there is the common problem of getting the noise level for a certain chance.
http://stackoverflow.com/questions/11487759/perlin-noise-to-percentage
Maybe you could include a getNoiseForChance(double chance) method?
Here is another example of someone struggling with the "chance" problem:
http://stackoverflow.com/questions/3696747/generation-of-uniformly-distributed-random-noise
This is fantastic. Thank you! I am deff going to give you credit in my work.
Awesome work! This was exactly what I was looking for. I'll add to my project and, of course, keep your name on it!!!
Bloody hell, this is a freaking long source. Any chance of a shorter implementation, perhaps a GLSL one?
Shouldn't it generate noise between -1 and 1? For the 2d implementation it seems to generate more like within an area of -0.87 to +0.87
I thing the norm constants haven't been chosen quite right.
@KdotJPG There seem to be few unused assignments: smcameron/open-simplex-noise-in-c#4
Any idea?
// Iterations: 100000000
2DOpenSimplexNoise speed: 6498.520513ms // this
2DSimplexNoise speed: 5000.267634ms // http://staffwww.itn.liu.se/~stegu/simplexnoise/SimplexNoise.java
// Iterations: 1000000
2DOpenSimplexNoise speed: 111.175103ms
2DSimplexNoise speed: 73.051068ms
////////////////////////////////////////////////////////////////
// After adding final to both implementation like so "public final class Name"
// Also I've separated the tests to avoid hot and cold scenario
// Iterations: 100000000
2DOpenSimplexNoise speed: 5702.409891ms
2DOpenSimplexNoise speed: 5675.584907ms
2DOpenSimplexNoise speed: 5863.16953ms
2DSimplexNoise speed: 4633.812286ms
2DSimplexNoise speed: 4524.991414ms
2DSimplexNoise speed: 4492.767565ms
2DSimplexNoise speed: 4649.350849ms
2DSimplexNoise speed: 4455.254193ms
2DSimplexNoise speed: 4633.330702ms
2DSimplexNoise speed: 4550.094936ms
// Best scenarios in this test
//
// 2DOpenSimplexNoise - 5675.584907ms
// 2DSimplexNoise - 4455.254193ms
// Worst scenarios in this test
//
// 2DOpenSimplexNoise - 5863.16953ms
// 2DSimplexNoise - 4649.350849ms
////////////////////////////////////////////////////////////////
// After removing final
2DOpenSimplexNoise speed: 5724.589568ms
2DOpenSimplexNoise speed: 5842.842763ms
2DOpenSimplexNoise speed: 5804.29675ms
2DOpenSimplexNoise speed: 5665.408102ms
2DSimplexNoise speed: 4581.063116ms
2DSimplexNoise speed: 4530.74752ms
2DSimplexNoise speed: 4590.37899ms
2DSimplexNoise speed: 4504.37333ms
// final seems to make no difference in this code
// Best scenarios in this test
//
// 2DOpenSimplexNoise - 5665.408102ms
// 2DSimplexNoise - 4504.37333ms
// Worst scenarios in this test
//
// 2DOpenSimplexNoise - 5842.842763ms
// 2DSimplexNoise - 4590.37899ms
////////////////////////////////////////////////////////////////
code:
public class SimplexNoisePerformanceTests {
private static int iterations = 100000000;
private static double x = 0.5447734756785486781d;
private static double y = 0.4923141242323442d;
public @Test void simplexNoise() {
final double[] result = new double[iterations];
final long start = System.nanoTime();
for (int i = 0; i < iterations; i++)
result[i] = SimplexNoise.noise(i*x, i*y);
long end = System.nanoTime() - start;
System.out.println("2DSimplexNoise speed: "+(end/1000000d)+"ms");
}
public @Test void openSimplexNoise() {
final double[] result = new double[iterations];
final OpenSimplexNoise simplex = new OpenSimplexNoise();
long start = System.nanoTime();
for (int i = 0; i < iterations; i++)
result[i] = simplex.eval(i*x, i*y);
long end = System.nanoTime() - start;
System.out.println("2DOpenSimplexNoise speed: "+(end/1000000d)+"ms");
}
}
Look like it's never touch -1 or 1
it's around -0.8 to +0.8
agree with Porama6400 interval should be betwwn -1 to 1, how to change code to get correct values?
https://eev.ee/blog/2016/05/29/perlin-noise/
Near the bottom, under "Some properties"
Contrary to popular belief — one espoused even by Ken Perlin! — the output range of Perlin noise is not -1 to 1. It’s ±½√n, where n is the number of dimensions. So a 1-D plane can never extend beyond -½ or ½ (which I bet you could prove if you thought about it), and the familiar 2-D noise is trapped within ±½√2 ≈ ±0.707 (which is also provable by extending the same thought a little further). If you’re using Perlin noise and expecting to span a specific range, make sure to take this into account.
I believe this should explain your issues with the range on OpenSimplex Noise; for 3D noise it would have a amplitude of ~0.866.
What's the reason for shifting seed
by 31
while permuting (source)? It seems like, for positive or negative seed
, it would just shift the input up by 31
, which could be taken care of in the LCG. I spent a decent amount of time researching that, and I couldn't find anything. Does it provide an extra layer of randomness on the off-chance the LCG aligns perfectly with the denominator?
I am doing eval(x,y,z,0) (4d noise with w=0) and it gives a range of about:
-0.6512914, 0.6200971
-0.77198315, 0.7699929
-0.6705122, 0.68826705
This is in a sample range of 16x256x16x0, or at point (x,y,z) the noise is eval(x,y,z,0).
Shouldnt it be +-(1/2)sqrt(4) = +-(1/2)2 = +-1?
@KdotJPG Please explain what all the different constants mean, how you got to them, and why this code can't be generalized to n
dimensions instead of just 2, 3, and 4. I want to write my own implementation in pure scala but this code is just a huge monster to tackle I can't really do it without explanation of the algorithm.
@KdotJPG Please explain what all the different constants mean, how you got to them, and why this code can't be generalized to
n
dimensions instead of just 2, 3, and 4. I want to write my own implementation in pure scala but this code is just a huge monster to tackle I can't really do it without explanation of the algorithm.
The actual paper is here, but it requires some higher level mathematics to understand: http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
OpenSimplex Noise, according to This Wikipedia Page, is slightly different in its implementation, though, in that:
- It uses a stretched simplectic honeycomb instead of a hypercubic honeycomb
- OpenSimplex noise uses a larger kernel size than Simplex noise, which results in slightly lost performance.
the paper you linked explains perlin vs simplex, not opensimplex.
Very good code thanks ! Only 1 question : how do you decrease the amplitude of the noise ? I'm getting a lot of big spikes in the values. I'd rather have bigger clusters of similar values. Thank you !
This is amazing!
Amazing! I use a modified version of this implementation in a small procedural terrain generator library: https://github.com/RedGalaxySW/Noise. Thanks a lot!
Thanks!
I made an Android library version from the latest revision
https://github.com/MarcoCiaramella/OpenSimplexNoise
@MarcoCiaramella Very cool! Out of curiosity, why not use the optimized version or even OpenSimplex2S? Either way I like that you continued with the public domain license.
@KdotJPG ok good thanks for your advice, I will do that!
C implementation https://github.com/MarcoCiaramella/OpenSimplex2
GPU implementation in OpenCL https://github.com/MarcoCiaramella/OpenSimplex2/tree/main/GPU/OpenCL
Thank you for this code!
Wow, great work!