001 package org.bukkit.util.noise; 002 003 import java.util.Random; 004 import org.bukkit.World; 005 006 /** 007 * Creates simplex noise through unbiased octaves 008 */ 009 public class SimplexOctaveGenerator extends OctaveGenerator { 010 private double wScale = 1; 011 012 /** 013 * Creates a simplex octave generator for the given world 014 * 015 * @param world World to construct this generator for 016 * @param octaves Amount of octaves to create 017 */ 018 public SimplexOctaveGenerator(World world, int octaves) { 019 this(new Random(world.getSeed()), octaves); 020 } 021 022 /** 023 * Creates a simplex octave generator for the given world 024 * 025 * @param seed Seed to construct this generator for 026 * @param octaves Amount of octaves to create 027 */ 028 public SimplexOctaveGenerator(long seed, int octaves) { 029 this(new Random(seed), octaves); 030 } 031 032 /** 033 * Creates a simplex octave generator for the given {@link Random} 034 * 035 * @param rand Random object to construct this generator for 036 * @param octaves Amount of octaves to create 037 */ 038 public SimplexOctaveGenerator(Random rand, int octaves) { 039 super(createOctaves(rand, octaves)); 040 } 041 042 @Override 043 public void setScale(double scale) { 044 super.setScale(scale); 045 setWScale(scale); 046 } 047 048 /** 049 * Gets the scale used for each W-coordinates passed 050 * 051 * @return W scale 052 */ 053 public double getWScale() { 054 return wScale; 055 } 056 057 /** 058 * Sets the scale used for each W-coordinates passed 059 * 060 * @param scale New W scale 061 */ 062 public void setWScale(double scale) { 063 wScale = scale; 064 } 065 066 /** 067 * Generates noise for the 3D coordinates using the specified number of 068 * octaves and parameters 069 * 070 * @param x X-coordinate 071 * @param y Y-coordinate 072 * @param z Z-coordinate 073 * @param w W-coordinate 074 * @param frequency How much to alter the frequency by each octave 075 * @param amplitude How much to alter the amplitude by each octave 076 * @return Resulting noise 077 */ 078 public double noise(double x, double y, double z, double w, double frequency, double amplitude) { 079 return noise(x, y, z, w, frequency, amplitude, false); 080 } 081 082 /** 083 * Generates noise for the 3D coordinates using the specified number of 084 * octaves and parameters 085 * 086 * @param x X-coordinate 087 * @param y Y-coordinate 088 * @param z Z-coordinate 089 * @param w W-coordinate 090 * @param frequency How much to alter the frequency by each octave 091 * @param amplitude How much to alter the amplitude by each octave 092 * @param normalized If true, normalize the value to [-1, 1] 093 * @return Resulting noise 094 */ 095 public double noise(double x, double y, double z, double w, double frequency, double amplitude, boolean normalized) { 096 double result = 0; 097 double amp = 1; 098 double freq = 1; 099 double max = 0; 100 101 x *= xScale; 102 y *= yScale; 103 z *= zScale; 104 w *= wScale; 105 106 for (NoiseGenerator octave : octaves) { 107 result += ((SimplexNoiseGenerator) octave).noise(x * freq, y * freq, z * freq, w * freq) * amp; 108 max += amp; 109 freq *= frequency; 110 amp *= amplitude; 111 } 112 113 if (normalized) { 114 result /= max; 115 } 116 117 return result; 118 } 119 120 private static NoiseGenerator[] createOctaves(Random rand, int octaves) { 121 NoiseGenerator[] result = new NoiseGenerator[octaves]; 122 123 for (int i = 0; i < octaves; i++) { 124 result[i] = new SimplexNoiseGenerator(rand); 125 } 126 127 return result; 128 } 129 }