package net.tropicraft.world.perlin; import java.util.Random; //TODO: Test and add new noise public class FishyNoise { int[] perm = new int[512]; public double[][] grad2d = new double[][] {{1, 0}, {.9239, .3827}, {.707107, 0.707107}, {.3827, .9239}, {0, 1}, {-.3827, .9239}, {-.707107, 0.707107},{-.9239, .3827}, {-1, 0}, {-.9239, -.3827}, {-.707107, -0.707107}, {-.3827, -.9239}, {0, -1}, {.3827, -.9239}, {.707107, -0.707107},{.9239, -.3827}}; public int[][] grad3d = new int[][] {{1, 1, 0}, {-1, 1, 0}, {1, -1, 0}, {-1, -1, 0}, {1, 0, 1}, {-1, 0, 1}, {1, 0, -1}, {-1, 0, -1}, {0, 1, 1}, {0, -1, 1}, {0, 1, -1}, {0, -1, -1}, {1, 1, 0}, {-1, 1, 0}, {0, -1, 1}, {0, -1, -1}}; public FishyNoise(long seed) { final Random rand = new Random(seed); for(int i = 0; i < 256; i++) { this.perm[i] = i; //Fill up the random array with numbers 0-256 } for(int i = 0; i < 256; i++) //Shuffle those numbers for the random effect { final int j = rand.nextInt(256); this.perm[i] = this.perm[i] ^ this.perm[j]; this.perm[j] = this.perm[i] ^ this.perm[j]; this.perm[i] = this.perm[i] ^ this.perm[j]; } for(int i = 0; i < 256; i++) { this.perm[i + 256] = this.perm[i]; } } private static double lerp(double x, double y, double n) { return x + n * (y - x); } private static int fastFloor(double x) { return x > 0 ? (int)x : (int)x - 1; } private static double fade(double n) { return n * n * n * (n * (n * 6 - 15) + 10); } private static double dot2(double[] grad2, double x, double y) { return grad2[0] * x + grad2[1] * y; } private static double dot3(int[] grad3, double x, double y, double z) { return grad3[0] * x + grad3[1] * y + grad3[2] * z; } public double noise2d(double x, double y) { int largeX = FishyNoise.fastFloor(x); int largeY = FishyNoise.fastFloor(y); x -= largeX; y -= largeY; largeX = largeX & 255; largeY = largeY & 255; final double u = FishyNoise.fade(x); final double v = FishyNoise.fade(y); final double grad00 = FishyNoise.dot2(this.grad2d[this.perm[largeX + this.perm[largeY]] & 15], x, y); final double grad01 = FishyNoise.dot2(this.grad2d[this.perm[largeX + this.perm[largeY + 1]] & 15], x, y - 1); final double grad11 = FishyNoise.dot2(this.grad2d[this.perm[largeX + 1 + this.perm[largeY + 1]] & 15], x - 1, y - 1); final double grad10 = FishyNoise.dot2(this.grad2d[this.perm[largeX + 1 + this.perm[largeY]] & 15], x - 1, y); final double lerpX0 = FishyNoise.lerp(grad00, grad10, u); final double lerpX1 = FishyNoise.lerp(grad01, grad11, u); return FishyNoise.lerp(lerpX0, lerpX1, v); } public double noise3d(double x, double y, double z) { int unitX = FishyNoise.fastFloor(x); int unitY = FishyNoise.fastFloor(y); int unitZ = FishyNoise.fastFloor(z); x -= unitX; y -= unitY; z -= unitZ; unitX = unitX & 255; unitY = unitY & 255; unitZ = unitZ & 255; final double u = FishyNoise.fade(x); final double v = FishyNoise.fade(y); final double w = FishyNoise.fade(z); final double grad000 = FishyNoise.dot3(this.grad3d[this.perm[unitX + this.perm[unitY + this.perm[unitZ]]] & 15], x, y, z); final double grad100 = FishyNoise.dot3(this.grad3d[this.perm[unitX + 1 + this.perm[unitY + this.perm[unitZ]]] & 15], x - 1, y, z); final double grad010 = FishyNoise.dot3(this.grad3d[this.perm[unitX + this.perm[unitY + 1 + this.perm[unitZ]]] & 15], x, y - 1, z); final double grad110 = FishyNoise.dot3(this.grad3d[this.perm[unitX + 1 + this.perm[unitY + 1 + this.perm[unitZ]]] & 15], x - 1, y - 1, z); final double grad001 = FishyNoise.dot3(this.grad3d[this.perm[unitX + this.perm[unitY + this.perm[unitZ + 1]]] & 15], x, y, z - 1); final double grad101 = FishyNoise.dot3(this.grad3d[this.perm[unitX + 1 + this.perm[unitY + this.perm[unitZ + 1]]] & 15], x - 1, y, z - 1); final double grad011 = FishyNoise.dot3(this.grad3d[this.perm[unitX + this.perm[unitY + 1 + this.perm[unitZ + 1]]] & 15], x, y - 1, z - 1); final double grad111 = FishyNoise.dot3(this.grad3d[this.perm[unitX + 1 + this.perm[unitY + 1 + this.perm[unitZ + 1]]] & 15], x - 1, y - 1, z - 1); return FishyNoise.lerp( FishyNoise.lerp( FishyNoise.lerp(grad000, grad100, u), FishyNoise.lerp(grad010, grad110, u), v), FishyNoise.lerp( FishyNoise.lerp(grad001, grad101, u), FishyNoise.lerp(grad011, grad111, u), v), w); } }