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 }