Advertisement
Guest User

Untitled

a guest
Nov 16th, 2019
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.60 KB | None | 0 0
  1. package ;
  2.  
  3. import java.util.Random;
  4.  
  5. import org.bukkit.util.noise.NoiseGenerator;
  6.  
  7. /**
  8. * This is a Voronoi noise generator, originally from
  9. * https://github.com/TJHJava/libnoiseforjava It was modified to work in a
  10. * similar way to the bukkit noise generators, and to support octaves and 2d
  11. * noise, by mncat77 and jtjj222.
  12. *
  13. * To use octaves, use the VoronoiOctaveGenerator class.
  14. *
  15. * Source:
  16. * https://github.com/justinmichaud/bukkit-terrain-tutorials/blob/master/7.5%
  17. * 20Cell%20Noise/src/main/java/me/jtjj222/ biomegen/VoronoiNoiseGenerator.java
  18. */
  19. public class VoronoiNoiseGenerator extends NoiseGenerator {
  20.  
  21. /// Noise module that outputs Voronoi cells.
  22. ///
  23. /// In mathematics, a <i>Voronoi cell</i> is a region containing all the
  24. /// points that are closer to a specific <i>seed point</i> than to any
  25. /// other seed point. These cells mesh with one another, producing
  26. /// polygon-like formations.
  27. ///
  28. /// By default, this noise module randomly places a seed point within
  29. /// each unit cube. By modifying the <i>frequency</i> of the seed points,
  30. /// an application can change the distance between seed points. The
  31. /// higher the frequency, the closer together this noise module places
  32. /// the seed points, which reduces the size of the cells. To specify the
  33. /// frequency of the cells, call the setFrequency() method.
  34. ///
  35. /// This noise module assigns each Voronoi cell with a random constant
  36. /// value from a coherent-noise function. The <i>displacement value</i>
  37. /// controls the range of random values to assign to each cell. The
  38. /// range of random values is +/- the displacement value. Call the
  39. /// setDisplacement() method to specify the displacement value.
  40. ///
  41. /// To modify the random positions of the seed points, call the SetSeed()
  42. /// method.
  43. ///
  44. /// This noise module can optionally add the distance from the nearest
  45. /// seed to the output value. To enable this feature, call the
  46. /// enableDistance() method. This causes the points in the Voronoi cells
  47. /// to increase in value the further away that point is from the nearest
  48. /// seed point.
  49.  
  50. // for speed, we can approximate the sqrt term in the distance functions
  51. // private static final float SQRT_2 = 1.4142135623730950488;
  52. private static final float ONE_DIV_SQRT_3 = (float) (1.0D / Math.sqrt(3.0D));
  53.  
  54. // You can either use the feature point height (for biomes or solid
  55. // pillars), or the distance to the feature point
  56. private final boolean useDistance;
  57. private final Random random;
  58.  
  59. private long seed;
  60.  
  61. public VoronoiNoiseGenerator(long seed, boolean useDistance) {
  62. this(new Random(seed), useDistance);
  63. }
  64.  
  65. public VoronoiNoiseGenerator(Random random, boolean useDistance) {
  66. this.seed = random.nextLong();
  67. this.random = random;
  68. this.useDistance = useDistance;
  69. }
  70.  
  71. public boolean isUseDistance() {
  72. return useDistance;
  73. }
  74.  
  75. public long getSeed() {
  76. return seed;
  77. }
  78.  
  79. public void setSeed(long seed) {
  80. this.seed = seed;
  81. }
  82.  
  83. @Override
  84. public double noise(double x, double z, double frequency) {
  85. x *= frequency;
  86. z *= frequency;
  87.  
  88. int xInt = (x > .0 ? (int) x : (int) x - 1);
  89. int zInt = (z > .0 ? (int) z : (int) z - 1);
  90.  
  91. double minDist = 32000000;
  92.  
  93. float xCandidate = 0;
  94. float zCandidate = 0;
  95.  
  96. random.setSeed(this.seed);
  97. long l = random.nextLong();
  98.  
  99. for (int zCur = zInt - 2; zCur <= zInt + 2; zCur++) {
  100. for (int xCur = xInt - 2; xCur <= xInt + 2; xCur++) {
  101.  
  102. float xPos = xCur + valueNoise2D(xCur, zCur, l);
  103. float zPos = zCur + valueNoise2D(xCur, zCur, seed);
  104. double xDist = xPos - x;
  105. double zDist = zPos - z;
  106. double dist = xDist * xDist + zDist * zDist;
  107.  
  108. if (dist < minDist) {
  109. minDist = dist;
  110. xCandidate = xPos;
  111. zCandidate = zPos;
  112. }
  113. }
  114. }
  115.  
  116. if (useDistance) {
  117. double xDist = xCandidate - x;
  118. double zDist = zCandidate - z;
  119. double squared = (xDist * xDist + zDist * zDist);
  120. double distance = Math.sqrt(squared) * ONE_DIV_SQRT_3;
  121. return distance;
  122. }
  123.  
  124. else
  125. return (VoronoiNoiseGenerator.valueNoise2D((int) (Math.floor(xCandidate)), (int) (Math.floor(zCandidate)),
  126. seed));
  127. }
  128.  
  129. public double[][] getClosestNeighbor( double x, double z, double frequency ) {
  130. x *= frequency;
  131. z *= frequency;
  132.  
  133. int xInt = (x > .0 ? (int) x : (int) x - 1);
  134. int zInt = (z > .0 ? (int) z : (int) z - 1);
  135.  
  136. double[][] neighbors = new double[ 5 ][ 3 ];
  137.  
  138. for ( double[] neighbor : neighbors ) {
  139. neighbor[ 0 ] = 32000000;
  140. }
  141.  
  142. random.setSeed(this.seed);
  143. long l = random.nextLong();
  144.  
  145. for (int zCur = zInt - 2; zCur <= zInt + 2; zCur++) {
  146. for (int xCur = xInt - 2; xCur <= xInt + 2; xCur++) {
  147.  
  148. float xPos = xCur + valueNoise2D(xCur, zCur, l);
  149. float zPos = zCur + valueNoise2D(xCur, zCur, seed);
  150. double xDist = xPos - x;
  151. double zDist = zPos - z;
  152. double dist = xDist * xDist + zDist * zDist;
  153.  
  154. double newV = dist;
  155. double newX = xPos;
  156. double newZ = zPos;
  157. for ( double[] neighbor : neighbors ) {
  158. if ( newV < neighbor[ 0 ] ) {
  159. double oldV = neighbor[ 0 ];
  160. double oldX = neighbor[ 1 ];
  161. double oldZ = neighbor[ 2 ];
  162.  
  163. neighbor[ 0 ] = newV;
  164. neighbor[ 1 ] = newX;
  165. neighbor[ 2 ] = newZ;
  166. newV = oldV;
  167. newX = oldX;
  168. newZ = oldZ;
  169. }
  170. }
  171. }
  172. }
  173.  
  174. double[][] values = new double[ neighbors.length ][];
  175. int index = 0;
  176. for ( double[] neighbor : neighbors ) {
  177. double value = VoronoiNoiseGenerator.valueNoise2D((int) (Math.floor(neighbor[ 1 ])), (int) (Math.floor(neighbor[ 2 ])), seed);
  178. double xDist = x - neighbor[ 1 ];
  179. double zDist = z - neighbor[ 2 ];
  180. // The first number is the height, and should range between 0 and 1
  181. // The second number should be the distance in the same scale as the parameters from the center of that cell
  182. values[ index++ ] = new double[] { ( value + 1 ) / 2.0, Math.sqrt( xDist * xDist + zDist * zDist ) / frequency, neighbor[ 1 ] / frequency, neighbor[ 2 ] / frequency };
  183. }
  184. return values;
  185. }
  186.  
  187. public float noise(float x, float y, float z, float frequency) {
  188. // Inside each unit cube, there is a seed point at a random position. Go
  189. // through each of the nearby cubes until we find a cube with a seed
  190. // point
  191. // that is closest to the specified position.
  192. x *= frequency;
  193. y *= frequency;
  194. z *= frequency;
  195.  
  196. int xInt = (x > .0 ? (int) x : (int) x - 1);
  197. int yInt = (y > .0 ? (int) y : (int) y - 1);
  198. int zInt = (z > .0 ? (int) z : (int) z - 1);
  199.  
  200. float minDist = 32000000.0F;
  201.  
  202. float xCandidate = 0;
  203. float yCandidate = 0;
  204. float zCandidate = 0;
  205.  
  206. random.setSeed(seed);
  207.  
  208. for (int zCur = zInt - 2; zCur <= zInt + 2; zCur++) {
  209. for (int yCur = yInt - 2; yCur <= yInt + 2; yCur++) {
  210. for (int xCur = xInt - 2; xCur <= xInt + 2; xCur++) {
  211. // Calculate the position and distance to the seed point
  212. // inside of
  213. // this unit cube.
  214.  
  215. float xPos = xCur + valueNoise3D(xCur, yCur, zCur, seed);
  216. float yPos = yCur + valueNoise3D(xCur, yCur, zCur, random.nextLong());
  217. float zPos = zCur + valueNoise3D(xCur, yCur, zCur, random.nextLong());
  218. float xDist = xPos - x;
  219. float yDist = yPos - y;
  220. float zDist = zPos - z;
  221. float dist = xDist * xDist + yDist * yDist + zDist * zDist;
  222.  
  223. if (dist < minDist) {
  224. // This seed point is closer to any others found so far,
  225. // so record
  226. // this seed point.
  227. minDist = dist;
  228. xCandidate = xPos;
  229. yCandidate = yPos;
  230. zCandidate = zPos;
  231. }
  232. }
  233. }
  234. }
  235. if (useDistance) {
  236. float xDist = xCandidate - x;
  237. float yDist = yCandidate - y;
  238. float zDist = zCandidate - z;
  239.  
  240. return (xDist * xDist + yDist * yDist + zDist * zDist);
  241. }
  242. return VoronoiNoiseGenerator.valueNoise3D(( int ) Math.floor(xCandidate), ( int ) Math.floor(yCandidate),
  243. ( int ) Math.floor(zCandidate), seed);
  244. }
  245.  
  246. /**
  247. * To avoid having to store the feature points, we use a hash function of
  248. * the coordinates and the seed instead. Those big scary numbers are
  249. * arbitrary primes.
  250. */
  251. public static float valueNoise2D(int x, int z, long seed) {
  252. long n = (1619 * x + 6971 * z + 1013 * seed) & 0x7fffffff;
  253. n = (n >> 13) ^ n;
  254. return 1.0f - (((n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff) / 1073741824.0f);
  255. }
  256.  
  257. public static float valueNoise3D(int x, int y, int z, long seed) {
  258. long n = (1619 * x + 31337 * y + 6971 * z + 1013 * seed) & 0x7fffffff;
  259. n = (n >> 13) ^ n;
  260. return 1.0f - (((n * (n * n * 60493 + 19990303) + 1376312589) & 0x7fffffff) / 1073741824.0f);
  261. }
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement