Guest User

Olsen Noise 3d Java

a guest
Feb 17th, 2015
400
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. /*
  3. * @author David Olsen
  4. */
  5.  
  6. public class OlsenNoise3D {
  7.  
  8. int maxiterations = 5;
  9. //you can mess with maxiterations all you'd want.
  10.  
  11. public double[][] olsennoise(int x, int y, int width, int height) {
  12. return normalized(olsennoise3d(maxiterations, 0, x, y, 2, x + width, y + height))[0];
  13. //this grabs a 2d slice of 3d noise.
  14. }
  15.  
  16. public double[][][] olsennoise(int x, int y, int z, int width, int height, int depth) {
  17. return normalized(olsennoise3d(maxiterations, x, y, z, x + width, y + height, z + depth));
  18. //gets a 3d section of noise.
  19. }
  20.  
  21. public double[][][] normalized(double[][][] arr) {
  22. double max = Double.NEGATIVE_INFINITY;
  23. double min = Double.POSITIVE_INFINITY;
  24. double mv;
  25.  
  26. for (int k = 0, n = arr.length; k < n; k++) {
  27. for (int j = 0, m = arr[0].length; j < m; j++) {
  28. for (int q = 0, p = arr[0][0].length; q < p; q++) {
  29. mv = arr[k][j][q];
  30. if (mv > max) {
  31. max = mv;
  32. }
  33. if (mv < min) {
  34. min = mv;
  35. }
  36. }
  37. } //find max/min
  38. }
  39.  
  40. double range = max - min;
  41. if (max != Integer.MIN_VALUE) {
  42.  
  43. for (int k = 0, n = arr.length; k < n; k++) {
  44. for (int j = 0, m = arr[0].length; j < m; j++) {
  45. for (int q = 0, p = arr[0][0].length; q < p; q++) {
  46.  
  47. arr[k][j][q] = (arr[k][j][q] - min) / range;
  48. }
  49. }
  50. }
  51. } //perform normalization.
  52. return arr;
  53. }
  54.  
  55. private void upsample(double[][][] from, double[][][] to) {
  56. for (int j = 0, m = from.length; j < m; j++) {
  57. for (int k = 0, n = from[0].length; k < n; k++) {
  58. for (int q = 0, p = from[0][0].length; q < p; q++) {
  59. for (int h = 0, g = 2 * 2 * 2; h < g; h++) {
  60. to[(j * 2) + ((h >> 2) & 1)][(k * 2) + ((h >> 1) & 1)][(q * 2) + (h & 1)] = from[j][k][q];
  61. }
  62. }
  63. }
  64. }//copy over the reused sections of field. Upsample.
  65. }
  66.  
  67. private void blur(double[][][] currentfield, double[][][] field) {
  68. for (int j = 0, m = field.length - 1; j < m; j++) {
  69. for (int k = 0, n = field[0].length - 1; k < n; k++) {
  70. for (int q = 0, p = field[0][0].length; q < p; q++) {
  71. int g = 3 * 3 * 3;
  72. for (int h = 0; h < g; h++) {
  73. field[j][k][q] += currentfield[j + (h % 3)][k + ((h / 3) % 3)][q + ((h / 9) % 3)];
  74. }
  75. field[j][k][q] /= g;
  76.  
  77. }
  78. }//blursubset.
  79. }
  80. }
  81.  
  82. private void noise(double[][][] field, int iterations, int x0, int y0, int z0) {
  83. for (int j = 0, m = field.length - 1; j < m; j++) {
  84. for (int k = 0, n = field[0].length - 1; k < n; k++) {
  85. for (int q = 0, p = field[0][0].length; q < p; q++) {
  86. field[j][k][q] += random(iterations, x0, y0, z0);
  87. }
  88. }//noise.
  89. }
  90. }
  91.  
  92. private double[][][] olsennoise3d(int iterations, int x0, int y0, int z0, int x1, int y1, int z1) {
  93. double[][][] field = new double[x1 - x0][y1 - y0][z1 - z0];
  94. if (iterations == 0) {
  95. //if this is the last iteration, provide a true random field.
  96. for (int j = 0, m = field.length; j < m; j++) {
  97. for (int k = 0, n = field[0].length; k < n; k++) {
  98. for (int q = 0, p = field[0][0].length; q < p; q++) {
  99. field[j][k][q] = (random(iterations, j + x0, k + y0, q + z0));
  100. }
  101. }
  102. }
  103. } else {
  104. //if this is not yet the last iteration, call for the upperfield recursively.
  105. double[][][] upperfield = olsennoise3d(iterations - 1, (x0 / 2) - 1, (y0 / 2) - 1, (z0 / 2) - 1, (x1 / 2) + (x1 & 1) + 1, (y1 / 2) + (y1 & 1) + 1, (z1 / 2) + (z1 & 1) + 1);
  106. //(x1&1) makes it a ceiling operation.
  107.  
  108. double[][][] currentfield = new double[upperfield.length * 2][upperfield[0].length * 2][upperfield[0][0].length * 2];
  109.  
  110. upsample(upperfield, currentfield); //upsample the field
  111. blur(currentfield, field); //blur the field
  112. noise(field, iterations, x0, y0, z0); //add noise to the field.
  113. //Those three operations are all that's required, that and scoping the field recusively so any request for any slice of the infinte field is complete
  114. //in a reasonable amount of time.
  115. }
  116. return field;
  117. }
  118.  
  119.  
  120. public double random(int iterations, int x, int y, int z) {
  121. return (((hashrandom(x,y,z,iterations) - 0.5) * 2)) / (1<<iterations);
  122. //This function controls the drop off rate for the noise. The noise added to each iteration should be greater at every lower iteration,
  123. //down to iteration 0 which is basically pure random.
  124. }
  125.  
  126. public double hashrandom(int... elements) {
  127. //To prevent repeating all that play a role in the request are hashed together.
  128. //This could be anything that gives a deterministic answer but seemingly random return value.
  129. long hash = 0;
  130.  
  131. for (int i = 0; i < elements.length; i++) {
  132. hash ^= elements[i];
  133. hash = hash(hash);
  134. }
  135. return (double)(hash & 0xFFFFFFF) / (double)0xFFFFFFF;
  136. }
  137.  
  138.  
  139. //This is a hash I found on the internet. It's just a good effective hash.
  140. public long hash(long v) {
  141. long hash = v;
  142. long h = hash;
  143.  
  144. switch ((int)hash & 3) {
  145. case 3:
  146. hash += h;
  147. hash ^= hash << 32;
  148. hash ^= h << 36;
  149. hash += hash >> 22;
  150. break;
  151. case 2:
  152. hash += h;
  153. hash ^= hash << 22;
  154. hash += hash >> 34;
  155. break;
  156. case 1:
  157. hash += h;
  158. hash ^= hash << 20;
  159. hash += hash >> 2;
  160. }
  161. hash ^= hash << 6;
  162. hash += hash >> 10;
  163. hash ^= hash << 8;
  164. hash += hash >> 34;
  165. hash ^= hash << 50;
  166. hash += hash >> 12;
  167. return hash;
  168. }
  169.  
  170.  
  171.  
  172. }
RAW Paste Data