| 1 | package kaka.cakelight.util; |
| 2 | |
| 3 | import java.util.Random; |
| 4 | |
| 5 | import static java.lang.Math.*; |
| 6 | |
| 7 | public class SimplexNoise3D { |
| 8 | private final byte[] ptab = new byte[256]; |
| 9 | private final double[][] gtab = { |
| 10 | { 1, 1, 0}, {-1, 1, 0}, { 1, -1, 0}, {-1, -1, 0}, |
| 11 | { 1, 0, 1}, {-1, 0, 1}, { 1, 0, -1}, {-1, 0, -1}, |
| 12 | { 0, 1, 1}, { 0, -1, 1}, { 0, 1, -1}, { 0, -1, -1}, |
| 13 | }; |
| 14 | |
| 15 | public SimplexNoise3D(Random rnd) { |
| 16 | for(int i = 0; i < 256; i++) |
| 17 | ptab[i] = (byte)i; |
| 18 | for(int i = 0; i < 256; i++) { |
| 19 | int r = rnd.nextInt(256); |
| 20 | byte t = ptab[i]; ptab[i] = ptab[r]; ptab[r] = t; |
| 21 | } |
| 22 | } |
| 23 | |
| 24 | public SimplexNoise3D(long seed) { |
| 25 | this(new Random(seed)); |
| 26 | } |
| 27 | |
| 28 | public SimplexNoise3D() { |
| 29 | this(new Random()); |
| 30 | } |
| 31 | |
| 32 | public double get(double r, double x, double y, double z) { |
| 33 | x /= r; y /= r; z /= r; |
| 34 | |
| 35 | double i, j, k; |
| 36 | { |
| 37 | double s = (x + y + z) / 3; |
| 38 | i = floor(x + s); |
| 39 | j = floor(y + s); |
| 40 | k = floor(z + s); |
| 41 | } |
| 42 | |
| 43 | double dx, dy, dz; |
| 44 | { |
| 45 | double s = (i + j + k) / 6; |
| 46 | dx = x - (i - s); |
| 47 | dy = y - (j - s); |
| 48 | dz = z - (k - s); |
| 49 | } |
| 50 | |
| 51 | int i1, j1, k1, i2, j2, k2; |
| 52 | if((dx >= dy) && (dy >= dz)) { |
| 53 | i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 1; k2 = 0; |
| 54 | } else if((dx >= dz) && (dz >= dy)) { |
| 55 | i1 = 1; j1 = 0; k1 = 0; i2 = 1; j2 = 0; k2 = 1; |
| 56 | } else if((dz >= dx) && (dx >= dy)) { |
| 57 | i1 = 0; j1 = 0; k1 = 1; i2 = 1; j2 = 0; k2 = 1; |
| 58 | } else if((dz >= dy) && (dy >= dx)) { |
| 59 | i1 = 0; j1 = 0; k1 = 1; i2 = 0; j2 = 1; k2 = 1; |
| 60 | } else if((dy >= dz) && (dz >= dx)) { |
| 61 | i1 = 0; j1 = 1; k1 = 0; i2 = 0; j2 = 1; k2 = 1; |
| 62 | } else /* if((dy >= dx) && (dx >= dz)) */ { |
| 63 | i1 = 0; j1 = 1; k1 = 0; i2 = 1; j2 = 1; k2 = 0; |
| 64 | } |
| 65 | |
| 66 | double x1 = dx - i1 + (1.0 / 6.0), y1 = dy - j1 + (1.0 / 6.0), z1 = dz - k1 + (1.0 / 6.0); |
| 67 | double x2 = dx - i2 + (1.0 / 3.0), y2 = dy - j2 + (1.0 / 3.0), z2 = dz - k2 + (1.0 / 3.0); |
| 68 | double x3 = dx - 0.5, y3 = dy - 0.5, z3 = dz - 0.5; |
| 69 | |
| 70 | int ip = (int)i, jp = (int)j, kp = (int)k; |
| 71 | double[] g0 = gtab[((int)ptab[(int)(ip + ptab[(int)(jp + ptab[(int)kp & 0xff]) & 0xff]) & 0xff] & 0xff) % 12]; |
| 72 | double[] g1 = gtab[((int)ptab[(int)(ip + i1 + ptab[(int)(jp + j1 + ptab[(int)(kp + k1) & 0xff]) & 0xff]) & 0xff] & 0xff) % 12]; |
| 73 | double[] g2 = gtab[((int)ptab[(int)(ip + i2 + ptab[(int)(jp + j2 + ptab[(int)(kp + k2) & 0xff]) & 0xff]) & 0xff] & 0xff) % 12]; |
| 74 | double[] g3 = gtab[((int)ptab[(int)(ip + 1 + ptab[(int)(jp + 1 + ptab[(int)(kp + 1) & 0xff]) & 0xff]) & 0xff] & 0xff) % 12]; |
| 75 | |
| 76 | double n0 = 0.6 - (dx * dx) - (dy * dy) - (dz * dz); |
| 77 | double n1 = 0.6 - (x1 * x1) - (y1 * y1) - (z1 * z1); |
| 78 | double n2 = 0.6 - (x2 * x2) - (y2 * y2) - (z2 * z2); |
| 79 | double n3 = 0.6 - (x3 * x3) - (y3 * y3) - (z3 * z3); |
| 80 | |
| 81 | double v = 0.0; |
| 82 | if(n0 > 0) v += n0 * n0 * n0 * n0 * ((g0[0] * dx) + (g0[1] * dy) + (g0[2] * dz)); |
| 83 | if(n1 > 0) v += n1 * n1 * n1 * n1 * ((g1[0] * x1) + (g1[1] * y1) + (g1[2] * z1)); |
| 84 | if(n2 > 0) v += n2 * n2 * n2 * n2 * ((g2[0] * x2) + (g2[1] * y2) + (g2[2] * z2)); |
| 85 | if(n3 > 0) v += n3 * n3 * n3 * n3 * ((g3[0] * x3) + (g3[1] * y3) + (g3[2] * z3)); |
| 86 | |
| 87 | return(min(max(v * 32, -1.0), 1.0)); |
| 88 | } |
| 89 | |
| 90 | public double getr(double lo, double hi, double r, double x, double y, double z) { |
| 91 | return((((get(r, x, y, z) * 0.5) + 0.5) * (hi - lo)) + lo); |
| 92 | } |
| 93 | |
| 94 | public int geti(int lo, int hi, double r, double x, double y, double z) { |
| 95 | return(min((int)(((get(r, x, y, z) * 0.5) + 0.5) * (hi - lo)), (int)((hi - lo) - 1)) + lo); |
| 96 | } |
| 97 | } |