New ambient mode
[kaka/cakelight.git] / src / kaka / cakelight / util / SimplexNoise3D.java
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 }