package maximusvladimir.dagen;
@SuppressWarnings("unused")
public class Perlin extends Generator {
private static int B = 0x1000;
private static int BM = 0xff;
private static int N = 0x1000;
private static int DEFAULT_SAMPLE_SIZE = 256;
private int[] p_imp;
private int[] p;
private float[][] g3;
private float[][] g2;
private float[] g1;
public Perlin(long seed, int width, int height) {
super(seed, width, height);
p_imp = new int[DEFAULT_SAMPLE_SIZE << 1];
int i, j, k;
for(i = 0; i < DEFAULT_SAMPLE_SIZE; i++)
p_imp[i] = i;
while(--i > 0)
{
k = p_imp[i];
j = (rand.nextInt(DEFAULT_SAMPLE_SIZE));
p_imp[i] = p_imp[j];
p_imp[j] = k;
}
initPerlin1();
}
public float noise(float x, float z) {
return (float)noise2(x,z); //improvedNoise(x,Constants.MAIN_RAND.nextDouble(),z);
}
public void generate() {
}
private double improvedNoise(double x, double y, double z)
{
int uc_x = (int)Math.floor(x) & 255;
int uc_y = (int)Math.floor(y) & 255;
int uc_z = (int)Math.floor(z) & 255;
double xo = x - Math.floor(x);
double yo = y - Math.floor(y);
double zo = z - Math.floor(z);
double u = fade(xo);
double v = fade(yo);
double w = fade(zo);
int a = p_imp[uc_x] + uc_y;
int aa = p_imp[a] + uc_z;
int ab = p_imp[a + 1] + uc_z;
int b = p_imp[uc_x + 1] + uc_y;
int ba = p_imp[b] + uc_z;
int bb = p_imp[b + 1] + uc_z;
double c1 = grad(p_imp[aa], xo, yo, zo);
double c2 = grad(p_imp[ba], xo - 1, yo, zo);
double c3 = grad(p_imp[ab], xo, yo - 1, zo);
double c4 = grad(p_imp[bb], xo - 1, yo - 1, zo);
double c5 = grad(p_imp[aa + 1], xo, yo, zo - 1);
double c6 = grad(p_imp[ba + 1], xo - 1, yo, zo - 1);
double c7 = grad(p_imp[ab + 1], xo, yo - 1, zo - 1);
double c8 = grad(p_imp[bb + 1], xo - 1, yo - 1, zo - 1);
return lerp(w, lerp(v, lerp(u, c1, c2), lerp(u, c3, c4)),
lerp(v, lerp(u, c5, c6), lerp(u, c7, c8)));
}
public float noise1(float x)
{
float t = x + N;
int bx0 = ((int) t) & BM;
int bx1 = (bx0 + 1) & BM;
float rx0 = t - (int) t;
float rx1 = rx0 - 1;
float sx = sCurve(rx0);
float u = rx0 * g1[p[bx0]];
float v = rx1 * g1[p[bx1]];
return lerp(sx, u, v);
}
public float noise2(float x, float y)
{
float t = x + N;
int bx0 = ((int)t) & BM;
int bx1 = (bx0 + 1) & BM;
float rx0 = t - (int)t;
float rx1 = rx0 - 1;
t = y + N;
int by0 = ((int)t) & BM;
int by1 = (by0 + 1) & BM;
float ry0 = t - (int)t;
float ry1 = ry0 - 1;
int i = p[bx0];
int j = p[bx1];
int b00 = p[i + by0];
int b10 = p[j + by0];
int b01 = p[i + by1];
int b11 = p[j + by1];
float sx = sCurve(rx0);
float sy = sCurve(ry0);
float[] q = g2[b00];
float u = rx0 * q[0] + ry0 * q[1];
q = g2[b10];
float v = rx1 * q[0] + ry0 * q[1];
float a = lerp(sx, u, v);
q = g2[b01];
u = rx0 * q[0] + ry1 * q[1];
q = g2[b11];
v = rx1 * q[0] + ry1 * q[1];
float b = lerp(sx, u, v);
//System.out.print("sy="+sy + "a="+a+"b="+b+ "sx="+sx+"u"+u+"v"+v);
return lerp(sy, a, b);
}
private float noise3(float x, float y, float z)
{
float t = x + N;
int bx0 = ((int)t) & BM;
int bx1 = (bx0 + 1) & BM;
float rx0 = t - (int)t;
float rx1 = rx0 - 1;
t = y + N;
int by0 = ((int)t) & BM;
int by1 = (by0 + 1) & BM;
float ry0 = t - (int)t;
float ry1 = ry0 - 1;
t = z + N;
int bz0 = ((int)t) & BM;
int bz1 = (bz0 + 1) & BM;
float rz0 = t - (int)t;
float rz1 = rz0 - 1;
int i = p[bx0];
int j = p[bx1];
int b00 = p[i + by0];
int b10 = p[j + by0];
int b01 = p[i + by1];
int b11 = p[j + by1];
t = sCurve(rx0);
float sy = sCurve(ry0);
float sz = sCurve(rz0);
float[] q = g3[b00 + bz0];
float u = (rx0 * q[0] + ry0 * q[1] + rz0 * q[2]);
q = g3[b10 + bz0];
float v = (rx1 * q[0] + ry0 * q[1] + rz0 * q[2]);
float a = lerp(t, u, v);
q = g3[b01 + bz0];
u = (rx0 * q[0] + ry1 * q[1] + rz0 * q[2]);
q = g3[b11 + bz0];
v = (rx1 * q[0] + ry1 * q[1] + rz0 * q[2]);
float b = lerp(t, u, v);
float c = lerp(sy, a, b);
q = g3[b00 + bz1];
u = (rx0 * q[0] + ry0 * q[1] + rz1 * q[2]);
q = g3[b10 + bz1];
v = (rx1 * q[0] + ry0 * q[1] + rz1 * q[2]);
a = lerp(t, u, v);
q = g3[b01 + bz1];
u = (rx0 * q[0] + ry1 * q[1] + rz1 * q[2]);
q = g3[b11 + bz1];
v = (rx1 * q[0] + ry1 * q[1] + rz1 * q[2]);
b = lerp(t, u, v);
float d = lerp(sy, a, b);
return lerp(sz, c, d);
}
private float noise3(double x, double y, double z) {
return noise3((float)x,(float)y,(float)z);
}
private double imporvedTurbulence(double x,
double y,
double z,
float loF,
float hiF)
{
double p_x = x + 123.456f;
double p_y = y;
double p_z = z;
double t = 0;
double f;
for(f = loF; f < hiF; f *= 2)
{
t += Math.abs(improvedNoise(p_x, p_y, p_z)) / f;
p_x *= 2;
p_y *= 2;
p_z *= 2;
}
return t - 0.3;
}
private float turbulence2(float x, float y, float freq)
{
float t = 0;
do
{
t += noise2(freq * x, freq * y) / freq;
freq *= 0.5f;
}
while (freq >= 1);
return t;
}
private float turbulence3(float x, float y, float z, float freq)
{
float t = 0;
do
{
t += noise3(freq * x, freq * y, freq * z) / freq;
freq *= 0.5f;
}
while (freq >= 1);
return t;
}
private float tileableNoise1(float x, float w)
{
return (noise1(x) * (w - x) +
noise1(x - w) * x) / w;
}
private float tileableNoise2(float x, float y, float w, float h)
{
return (noise2(x, y) * (w - x) * (h - y) +
noise2(x - w, y) * x * (h - y) +
noise2(x, y - h) * (w - x) * y +
noise2(x - w, y - h) * x * y) / (w * h);
}
private float fmod(float n, float d) {
float x=n/d;
return n-floor(x)*d;
}
private int floor(float a) {
if (a>=0) return (int)a;
int x=(int)a;
return (a==x)?x:x-1;
}
private float tileableNoise3(float x,
float y,
float z,
float w,
float h,
float d)
{
x=fmod(x,w);
y=fmod(y,h);
z=fmod(z,d);
return (noise3(x, y, z) * (w - x) * (h - y) * (d - z) +
noise3(x - w, y, z) * x * (h - y) * (d - z) +
noise3(x, y - h, z) * (w - x) * y * (d - z) +
noise3(x - w, y - h, z) * x * y * (d - z) +
noise3(x, y, z - d) * (w - x) * (h - y) * z +
noise3(x - w, y, z - d) * x * (h - y) * z +
noise3(x, y - h, z - d) * (w - x) * y * z +
noise3(x - w, y - h, z - d) * x * y * z) /
(w * h * d);
}
private float tileableTurbulence2(float x,
float y,
float w,
float h,
float freq)
{
float t = 0;
do
{
t += tileableNoise2(freq * x, freq * y, w * freq, h * freq) / freq;
freq *= 0.5f;
}
while (freq >= 1);
return t;
}
private float tileableTurbulence3(float x,
float y,
float z,
float w,
float h,
float d,
float freq)
{
float t = 0;
do
{
t += tileableNoise3(freq * x,
freq * y,
freq * z,
w * freq,
h * freq,
d * freq) / freq;
freq *= 0.5f;
}
while (freq >= 1);
return t;
}
private double lerp(double t, double a, double b)
{
return a + t * (b - a);
}
private float lerp(float t, float a, float b)
{
return a + t * (b - a);
}
private double fade(double t)
{
return t * t * t * (t * (t * 6 - 15) + 10);
}
private double grad(int hash, double x, double y, double z)
{
int h = hash & 15;
double u = (h < 8 || h == 12 || h == 13) ? x : y;
double v = (h < 4 || h == 12 || h == 13) ? y : z;
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
private float sCurve(float t)
{
return (t * t * (3 - 2 * t));
}
private void normalize2(float[] v)
{
float s = (float)(1 / Math.sqrt(v[0] * v[0] + v[1] * v[1]));
v[0] *= s;
v[1] *= s;
}
private void normalize3(float[] v)
{
float s = (float)(1 / Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]));
v[0] *= s;
v[1] *= s;
v[2] *= s;
}
private void initPerlin1()
{
p = new int[B + B + 2];
g3 = new float[B + B + 2][3];
g2 = new float[B + B + 2][2];
g1 = new float[B + B + 2];
int i, j, k;
for(i = 0; i < B; i++)
{
p[i] = i;
g1[i] = (float)((rand.nextInt(B + B)) - B) / B;
for(j = 0; j < 2; j++)
g2[i][j] = (float)((rand.nextInt(B + B)) - B) / B;
normalize2(g2[i]);
for(j = 0; j < 3; j++)
g3[i][j] = (float)((rand.nextInt(B + B)) - B) / B;
normalize3(g3[i]);
}
while(--i > 0)
{
k = p[i];
j = (rand.nextInt(B));
p[i] = p[j];
p[j] = k;
}
for(i = 0; i < B + 2; i++)
{
p[B + i] = p[i];
g1[B + i] = g1[i];
for(j = 0; j < 2; j++)
g2[B + i][j] = g2[i][j];
for(j = 0; j < 3; j++)
g3[B + i][j] = g3[i][j];
}
}
}