public class Perlin{ protected int seed; protected int RES; protected int BIT_OFFSET; protected int fieldRes; protected int[] blend; protected int scale; protected int[] freq; protected int[] amplitudes; protected final int offset = 470317; //------------------------ public int getSeed(float fscale){ return seed; } //------------------------ public void setSeed(int seed){ this.seed = seed; makeField(); } //------------------------ public float getScale(){ return scale/(float)RES; } //------------------------ public void setScale(float fscale){ this.scale = (int) (RES*fscale); } //------------------------ public void setDetail(int levels){ makeOctaveLUT(levels); } //------------------------ public void setFieldDetail(int fieldRes){ this.fieldRes = fieldRes; makeField(); } //------------------------ public void linearBlend(){ blend = new int[RES]; for(int i=0 ; i>> BIT_OFFSET; } return sum/(float)RES; } //------------------------ private int getOctave(int x){ // corner point indices (High or Low) int LX = (x >>> BIT_OFFSET) % fieldRes; int HX = (LX==fieldRes-1 ? 0 : LX+1); // (b-prefix) : blending amounts int bX = blend[x & (RES-1)]; // corner point values (High or Low) return (field[ LX ]*(RES-bX) + field[ HX ]*bX) >>> BIT_OFFSET; } } public class Perlin2D extends Perlin{ private int[][] field; //------------------------ public Perlin2D(){ this(0.02); } //------------------------ public Perlin2D(float fscale){ this(fscale,4); } //------------------------ public Perlin2D(float fscale, int levels){ this(fscale,levels,(new Random()).nextInt()); } //------------------------ public Perlin2D(float fscale, int levels, int seed){ this(10,64,fscale,levels,seed); } //------------------------ public Perlin2D(int BIT_OFFSET, int fieldRes, float fscale, int levels, int seed){ this.fieldRes = fieldRes; this.BIT_OFFSET = BIT_OFFSET; this.RES = 1 << BIT_OFFSET; this.scale = (int) (RES*fscale); this.amplitudes = new int[]{RES/2,RES/4,RES/8,RES/16}; this.seed = seed; makeField(); cosineBlend(); makeOctaveLUT(levels); } //------------------------ protected void makeField(){ Random perlinRandom = new Random(seed); field = new int[fieldRes][fieldRes]; for(int x=0 ; x>> BIT_OFFSET; } return sum/(float)RES; } //------------------------ private int getOctave(int x, int y){ // corner point indices (High or Low) int LX = (x >>> BIT_OFFSET) % fieldRes; int LY = (y >>> BIT_OFFSET) % fieldRes; int HX = (LX==fieldRes-1 ? 0 : LX+1); int HY = (LY==fieldRes-1 ? 0 : LY+1); // (b-prefix) : blending amounts int bX = blend[x & (RES-1)]; int bY = blend[y & (RES-1)]; // corner point values (High or Low) int A = (field[ LX ][ LY ]*(RES-bX) + field[ HX ][ LY ]*bX) >>> BIT_OFFSET; int B = (field[ LX ][ HY ]*(RES-bX) + field[ HX ][ HY ]*bX) >>> BIT_OFFSET; return (A*(RES-bY) + B*bY) >>> BIT_OFFSET; } } class Perlin3D extends Perlin{ private int[][][] field; //------------------------ public Perlin3D(){ this(0.02); } //------------------------ public Perlin3D(float fscale){ this(fscale,4); } //------------------------ public Perlin3D(float fscale, int levels){ this(fscale,levels,(new Random()).nextInt()); } //------------------------ public Perlin3D(float fscale, int levels, int seed){ this(10,16,fscale,levels,seed); } //------------------------ public Perlin3D(int BIT_OFFSET, int fieldRes, float fscale, int levels, int seed){ this.fieldRes = fieldRes; this.BIT_OFFSET = BIT_OFFSET; this.RES = 1 << BIT_OFFSET; this.scale = (int) (RES*fscale); this.amplitudes = new int[]{RES/2,RES/4,RES/8,RES/16}; this.seed = seed; makeField(); cosineBlend(); makeOctaveLUT(levels); } //------------------------ protected void makeField(){ Random perlinRandom = new Random(seed); field = new int[fieldRes][fieldRes][fieldRes]; for(int x=0 ; x>> BIT_OFFSET; } return sum/(float)RES; } //------------------------ private int getOctave(int x, int y, int z){ // corner point indices (High or Low) int LX = (x >>> BIT_OFFSET) % fieldRes; int LY = (y >>> BIT_OFFSET) % fieldRes; int LZ = (z >>> BIT_OFFSET) % fieldRes; int HX = (LX==fieldRes-1 ? 0 : LX+1); int HY = (LY==fieldRes-1 ? 0 : LY+1); int HZ = (LZ==fieldRes-1 ? 0 : LZ+1); // (b-prefix) : blending amounts int bX = blend[x & (RES-1)]; int bY = blend[y & (RES-1)]; int bZ = blend[z & (RES-1)]; // corner point values (High or Low) int A = (field[ LX ][ LY ][ LZ ]*(RES-bX) + field[ HX ][ LY ][ LZ ]*bX) >>> BIT_OFFSET; int B = (field[ LX ][ LY ][ HZ ]*(RES-bX) + field[ HX ][ LY ][ HZ ]*bX) >>> BIT_OFFSET; int C = (field[ LX ][ HY ][ LZ ]*(RES-bX) + field[ HX ][ HY ][ LZ ]*bX) >>> BIT_OFFSET; int D = (field[ LX ][ HY ][ HZ ]*(RES-bX) + field[ HX ][ HY ][ HZ ]*bX) >>> BIT_OFFSET; int E = (A*(RES-bY) + C*bY) >>> BIT_OFFSET; int F = (B*(RES-bY) + D*bY) >>> BIT_OFFSET; return (E*(RES-bZ) + F*bZ) >>> BIT_OFFSET; } }