Guest User

Untitled

a guest
Jan 18th, 2019
165
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.38 KB | None | 0 0
  1. package io.github.opencubicchunks.cubicchunks.cubicgen.noise;
  2.  
  3. import com.flowpowered.noise.Utils;
  4. import com.flowpowered.noise.module.Module;
  5. import io.github.opencubicchunks.cubicchunks.cubicgen.math.Vec2d;
  6. import net.minecraft.util.math.MathHelper;
  7.  
  8. public class BiomeControlledGradValPerlinNoise extends Module {
  9. private static final int X_NOISE_GEN = 1619;
  10. private static final int Y_NOISE_GEN = 31337;
  11. private static final int Z_NOISE_GEN = 6971;
  12. private static final int SEED_NOISE_GEN = 1013;
  13. private static final int SHIFT_NOISE_GEN = 8;
  14.  
  15. private final double maxVal;
  16. private int octaves;
  17. private double fx;
  18. private double fy;
  19. private double fz;
  20. private double valleyDepthFactor;
  21. private final double scale;
  22. private final double offset;
  23. private final double fxi;
  24. private final double fyi;
  25. private final double fzi;
  26. private final int seed;
  27.  
  28. private BiomeDataProvider data;
  29.  
  30. /**
  31. * Generates a gradient-coherent-noise value from the coordinates of a three-dimensional input value.
  32. *
  33. * @param x The @a x coordinate of the input value.
  34. * @param y The @a y coordinate of the input value.
  35. * @param z The @a z coordinate of the input value.
  36. * @param seed The random number seed.
  37. * @param valleyDepthFactor
  38. * @return The generated gradient-coherent-noise value.
  39. * <p/>
  40. * The return value ranges from 0 to 1.
  41. * <p/>
  42. * For an explanation of the difference between <i>gradient</i> noise and <i>value</i> noise, see the comments for the GradientNoise3D() function.
  43. */
  44. public static void gradientCoherentNoise3D(double x, double y, double z,
  45. double freqInvX, double freqInvY, double freqInvZ,
  46. int seed, BiomeDataProvider data, double valleyDepthFactor,
  47. Vec2d output) {
  48.  
  49. // Create a unit-length cube aligned along an integer boundary. This cube
  50. // surrounds the input point.
  51.  
  52. int x0 = ((x > 0.0) ? (int) x : (int) x - 1);
  53. int x1 = x0 + 1;
  54.  
  55. int y0 = ((y > 0.0) ? (int) y : (int) y - 1);
  56. int y1 = y0 + 1;
  57.  
  58. int z0 = ((z > 0.0) ? (int) z : (int) z - 1);
  59. int z1 = z0 + 1;
  60.  
  61. // world coordinates for biome data
  62. int wx0 = MathHelper.floor(x0 * freqInvX);
  63. int wy0 = MathHelper.floor(y0 * freqInvY);
  64. int wz0 = MathHelper.floor(z0 * freqInvZ);
  65.  
  66. int wx1 = MathHelper.floor(x1 * freqInvX);
  67. int wy1 = MathHelper.floor(y1 * freqInvY);
  68. int wz1 = MathHelper.floor(z1 * freqInvZ);
  69.  
  70. // Map the difference between the coordinates of the input value and the
  71. // coordinates of the cube's outer-lower-left vertex onto an S-curve.
  72. double xs = Utils.sCurve5(x - (double) x0);
  73. double ys = Utils.sCurve5(y - (double) y0);
  74. double zs = Utils.sCurve5(z - (double) z0);
  75.  
  76. // Now calculate the noise values at each vertex of the cube. To generate
  77. // the coherent-noise value at the input point, interpolate these eight
  78. // noise values using the S-curve value as the interpolant (trilinear
  79. // interpolation.)
  80. Vec2d n0 = new Vec2d(0, 0);
  81. Vec2d n1 = new Vec2d(0, 0);
  82. Vec2d ix0 = new Vec2d(0, 0);
  83. Vec2d ix1 = new Vec2d(0, 0);
  84. Vec2d iy0 = new Vec2d(0, 0);
  85. Vec2d iy1 = new Vec2d(0, 0);
  86.  
  87. gradvalBiomeNoise3D(x, y, z, x0, y0, z0, wx0, wy0, wz0, seed, data, n0);
  88. gradvalBiomeNoise3D(x, y, z, x1, y0, z0, wx1, wy0, wz0, seed, data, n1);
  89. linearInterp(n0, n1, xs, ix0);
  90.  
  91. gradvalBiomeNoise3D(x, y, z, x0, y1, z0, wx0, wy1, wz0, seed, data, n0);
  92. gradvalBiomeNoise3D(x, y, z, x1, y1, z0, wx1, wy1, wz0, seed, data, n1);
  93. linearInterp(n0, n1, xs, ix1);
  94. linearInterp(ix0, ix1, ys, iy0);
  95.  
  96. gradvalBiomeNoise3D(x, y, z, x0, y0, z1, wx0, wy0, wz1, seed, data, n0);
  97. gradvalBiomeNoise3D(x, y, z, x1, y0, z1, wx1, wy0, wz1, seed, data, n1);
  98. linearInterp(n0, n1, xs, ix0);
  99. gradvalBiomeNoise3D(x, y, z, x0, y1, z1, wx0, wy1, wz1, seed, data, n0);
  100. gradvalBiomeNoise3D(x, y, z, x1, y1, z1, wx1, wy1, wz1, seed, data, n1);
  101. linearInterp(n0, n1, xs, ix1);
  102. linearInterp(ix0, ix1, ys, iy1);
  103.  
  104. linearInterp(iy0, iy1, zs, output);
  105. }
  106.  
  107. private static void linearInterp(Vec2d x0, Vec2d x1, double a, Vec2d out) {
  108. out.x = Utils.linearInterp(x0.x, x1.x, a);
  109. out.y = Utils.linearInterp(x0.y, x1.y, a);
  110. }
  111.  
  112. /**
  113. * Generates mixed gradient and value noise using biome data basis for given coordinates,
  114. * specified as pair of integer and fractional parts.
  115. * <p>
  116. * The difference between fx and ix must be less than or equal to one.
  117. * The difference between @a fy and @a iy must be less than or equal to one.
  118. * The difference between @a fz and @a iz must be less than or equal to one.
  119. * <p/>
  120. * The noise gen
  121. * <p/>
  122. * The gradient part ranges from -1 to 1 multiplied by biome factor.
  123. * The value part is biome offset.
  124. * <p/>
  125. * This function generates a gradient-noise value by performing the following steps: - It first calculates a random normalized vector based on the nearby integer value passed to this function. -
  126. * It then calculates a new value by adding this vector to the nearby integer value passed to this function. - It then calculates the dot product of the above-generated value and the
  127. * floating-point input value passed to this function.
  128. * <p/>
  129. * A noise function differs from a random-number generator because it always returns the same output value if the same input value is passed to it.
  130. *
  131. * @param fx The floating-point @a x coordinate of the input value.
  132. * @param fy The floating-point @a y coordinate of the input value.
  133. * @param fz The floating-point @a z coordinate of the input value.
  134. * @param ix The integer @a x coordinate of a nearby value.
  135. * @param iy The integer @a y coordinate of a nearby value.
  136. * @param iz The integer @a z coordinate of a nearby value.
  137. * @param wx World x coordinate for biome data
  138. * @param wy World y coordinate for biome data
  139. * @param wz World z coordinate for biome data
  140. * @param seed The random number seed.
  141. * @param data Source of biome data
  142. * @param output The output value. x is gradient component, y is value component
  143. */
  144. public static void gradvalBiomeNoise3D(double fx, double fy, double fz,
  145. int ix, int iy, int iz,
  146. int wx, int wy, int wz,
  147. int seed, BiomeDataProvider data, Vec2d output) {
  148.  
  149. data.prepare(wx, wy, wz);
  150. double factor = data.variation() * 2; // * 2 because RANDOM_VECTORS is halved as an optimization
  151.  
  152. // Randomly generate a gradient vector given the integer coordinates of the
  153. // input value. This implementation generates a random number and uses it
  154. // as an index into a normalized-vector lookup table.
  155. int vectorIndex = (X_NOISE_GEN * ix + Y_NOISE_GEN * iy + Z_NOISE_GEN * iz + SEED_NOISE_GEN * seed);
  156. vectorIndex ^= (vectorIndex >> SHIFT_NOISE_GEN);
  157. vectorIndex &= 0xff;
  158.  
  159. double xvGradient = Utils.RANDOM_VECTORS[(vectorIndex << 2)] * factor;
  160. double yvGradient = Utils.RANDOM_VECTORS[(vectorIndex << 2) + 1] * factor;
  161. double zvGradient = Utils.RANDOM_VECTORS[(vectorIndex << 2) + 2] * factor;
  162.  
  163. // Set up us another vector equal to the distance between the two vectors
  164. // passed to this function.
  165. double xvPoint = (fx - ix);
  166. double yvPoint = (fy - iy);
  167. double zvPoint = (fz - iz);
  168.  
  169. // Now compute the dot product of the gradient vector with the distance
  170. // vector. The resulting value is gradient noise. Apply a scaling and
  171. // offset value so that this noise value ranges from 0 to 1.
  172. output.x = (xvGradient * xvPoint) + (yvGradient * yvPoint) + (zvGradient * zvPoint);
  173. output.y = data.offset();
  174. }
  175.  
  176. public BiomeControlledGradValPerlinNoise(BiomeDataProvider data, int octaves, long seed,
  177. boolean normalized, double minNorm, double maxNorm,
  178. double fx, double fy, double fz, double valleyDepthFactor) {
  179. super(0);
  180. this.data = data;
  181.  
  182. this.fx = fx;
  183. this.fy = fy;
  184. this.fz = fz;
  185.  
  186. fxi = 1.0/fx;
  187. fyi = 1.0/fy;
  188. fzi = 1.0/fz;
  189.  
  190. maxVal = (Math.pow(0.5, octaves) - 1) / (0.5 - 1);
  191. scale = normalized ? (1.0/maxVal) * (maxNorm - minNorm) / 2 : 1;
  192. offset = normalized ? (maxNorm + minNorm) / 2 : 0;
  193.  
  194. this.octaves = octaves;
  195. this.valleyDepthFactor = valleyDepthFactor;
  196. this.seed = (int) (seed ^ (seed >>> 32));
  197. }
  198.  
  199. @Override
  200. public int getSourceModuleCount() {
  201. return 0;
  202. }
  203.  
  204. @Override
  205. public double getValue(double x, double y, double z) {
  206. double x1 = x;
  207. double y1 = y;
  208. double z1 = z;
  209.  
  210. double fxi = this.fxi;
  211. double fyi = this.fyi;
  212. double fzi = this.fzi;
  213.  
  214. double curPersistence = 1.0;
  215. int seed;
  216.  
  217. x1 *= fx;
  218. y1 *= fy;
  219. z1 *= fz;
  220.  
  221. Vec2d out = new Vec2d(0, 0);
  222. Vec2d temp = new Vec2d(0, 0);
  223.  
  224. for (int curOctave = 0; curOctave < octaves; curOctave++) {
  225. // Get the coherent-noise value from the input value and add it to the
  226. // final result.
  227. seed = this.seed + curOctave;
  228. BiomeControlledGradValPerlinNoise.gradientCoherentNoise3D(
  229. x1, y1, z1, fxi, fyi, fzi,
  230. seed, data, valleyDepthFactor, temp);
  231. out.add(temp.mul(curPersistence));
  232.  
  233. // Prepare the next octave.
  234. x1 *= 2;
  235. y1 *= 2;
  236. z1 *= 2;
  237. fxi *= 0.5;
  238. fyi *= 0.5;
  239. fzi *= 0.5;
  240. curPersistence *= 0.5;
  241. }
  242.  
  243. out.mul(scale).add(offset);
  244.  
  245. if (y < out.y) {
  246. out.x *= valleyDepthFactor;
  247. }
  248.  
  249. return out.x + out.y;
  250. }
  251.  
  252. public interface BiomeDataProvider {
  253. void prepare(int x, int y, int z);
  254.  
  255. double variation();
  256.  
  257. double offset();
  258. }
  259. }
Add Comment
Please, Sign In to add comment