Advertisement
Tatarize

Incomplete Olsen Noise Algorithm

Feb 19th, 2015
297
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.76 KB | None | 0 0
  1.  
  2. import java.util.Arrays;
  3.  
  4. /**
  5. * Created by Tat on 2/17/2015.
  6. */
  7.  
  8. public class OlsenNoise2D {
  9.  
  10. public static void convolve(int[] pixels, int offset, int stride, int x, int y, int width, int height, int[][] matrix, int parts) {
  11. int startIndex = x + (y * stride);
  12. int lastIndex = (x + width - 1) + ((y + height - 1) * stride);
  13. int x_pos = x;
  14. int y_pos = y;
  15. int indexInc = 1;
  16. int yinc = 0;
  17. int xinc = 1;
  18.  
  19. for (int i = 0, s = width + height; i < s; i++) {
  20. if (i == width) {
  21. indexInc = stride;
  22. yinc = 1;
  23. xinc = 0;
  24. }
  25. int x_counter = x_pos;
  26. int index = startIndex;
  27. while (x_counter >= x && index <= lastIndex) {
  28. pixels[offset + index] = convolve(pixels, stride, offset + index, matrix, parts);
  29. x_counter--;
  30. index += stride - 1;
  31. }
  32. startIndex += indexInc;
  33. x_pos += xinc;
  34. y_pos += yinc;
  35. }
  36. }
  37.  
  38.  
  39. private static int crimp(int color) {
  40. return (color >= 0xFF) ? 0xFF : (color < 0) ? 0 : color;
  41. }
  42.  
  43. private static int convolve(int[] pixels, int stride, int index, int[][] matrix, int parts) {
  44. int redSum = 0;
  45. int greenSum = 0;
  46. int blueSum = 0;
  47. int pixel, factor;
  48. for (int j = 0, m = matrix.length; j < m; j++, index++) {
  49. for (int k = 0, n = matrix[j].length, q = index; k < n; k++, q += stride) {
  50. pixel = pixels[q];
  51. factor = matrix[j][k];
  52. redSum += factor * ((pixel >> 16) & 0xFF);
  53. greenSum += factor * ((pixel >> 8) & 0xFF);
  54. blueSum += factor * ((pixel) & 0xFF);
  55. }
  56. }
  57. return 0xFF000000 | ((crimp(redSum / parts) << 16) | (crimp(greenSum / parts) << 8) | (crimp(blueSum / parts)));
  58. }
  59.  
  60. //occupies same footprint
  61. private void applyNoise(int[] pixels, int stride, int x_within_scope, int y_within_scope, int x_within_field, int y_within_field, int width, int height, int iteration) {
  62. int index = (y_within_scope * stride);
  63. for (int k = y_within_scope, n = y_within_scope + height - 1; k <= n; k++, index += stride) {
  64. for (int j = x_within_scope, m = x_within_scope + width - 1; j <= m; j++) {
  65. int current = index + j;
  66. pixels[current] += (hashrandom(x_within_field + j, y_within_field + k, iteration) & (1 << (7 - iteration)));
  67. }
  68. }
  69. }
  70.  
  71. //requires half the height and width be good.
  72. private void applyScale(int[] pixels, int stride, int x_within_scope, int y_within_scope, int width, int height) {
  73. int index = (y_within_scope + height - 1) * stride;
  74. for (int k = y_within_scope, n = y_within_scope + height - 1; k <= n; n--, index -= stride) {
  75. for (int j = x_within_scope, m = x_within_scope + width - 1; j <= m; m--) {
  76. int current = index + m;
  77. int lower = ((n / 2) * stride) + (m / 2);
  78. pixels[current] = pixels[lower];
  79. }
  80. }
  81. }
  82.  
  83.  
  84. //requires width + 1 valid, height + 1
  85. private static final int[][] blur2x2 = new int[][]{
  86. {1, 1},
  87. {1, 1},
  88. };
  89.  
  90. private void applyBlur(int[] pixels, int stride, int x_within_scope, int y_within_scope, int width, int height) {
  91. convolve(pixels, 0, stride, x_within_scope, y_within_scope, width, height, blur2x2, 4);
  92. }
  93.  
  94. //You need to give it an array larger than the current one. This math is just a guess at a number big enough, it's not actually the max dim the array would properly need to be.
  95. public int getRequiredDim(int dim) {
  96. return (dim + 5) * 2;
  97. }
  98. private void trim(int[] pixels, int width, int height, int[] workingpixels, int workingstride) {
  99. for (int k = 0; k < height; k++) {
  100. for (int j = 0; j < width; j++) {
  101. int index = j + (k * width);
  102. int workingindex = j + (k * workingstride);
  103. pixels[index] = workingpixels[workingindex];
  104. }
  105. }
  106. }
  107.  
  108. static final int maxiterations = 7;
  109. public void olsennoise(int[] pixels, int stride, int x, int y, int width, int height) {
  110. Arrays.fill(pixels, 0xFF000000);
  111. olsennoise(pixels, stride, 0, 0, x, y, width, height, maxiterations);
  112. }
  113.  
  114. public void olsennoise(int[] pixels, int stride, int x_within_scope, int y_within_scope, int x_within_field, int y_within_field, int width, int height, int iteration) {
  115. if (iteration == 0) {
  116. applyNoise(pixels, stride, x_within_scope, y_within_scope, x_within_field, y_within_field, width, height, iteration);
  117. return;
  118. }
  119.  
  120.  
  121. //Simply an answer, not the correct one. It needs to fix the scoping. I don't need as many good bits as I properly give currently. And it needs to adjust the x, and y.
  122. //if the x and y are off it'll move right because the same location isn't queried the same way to make the same data.
  123.  
  124. olsennoise(pixels, stride, x_within_scope, y_within_scope, x_within_field, y_within_field, width + 1, height + 1, iteration - 1);
  125.  
  126. //scale only requires (width/2+1) and (height/2+1) valid pixels.
  127. applyScale(pixels, stride, x_within_scope, y_within_scope, width, height);
  128.  
  129. //blur only requires width+1 and height+1 valid pixels.
  130. applyBlur(pixels, stride, x_within_scope, y_within_scope, width, height);
  131.  
  132. //noise requires width, and height valid pixels
  133. applyNoise(pixels, stride, x_within_scope, y_within_scope, x_within_field, y_within_field, width, height, iteration);
  134. }
  135.  
  136.  
  137. public static int hashrandom(int... elements) {
  138. long hash = 0;
  139. for (int i = 0; i < elements.length; i++) {
  140. hash ^= elements[i];
  141. hash = hash(hash);
  142. }
  143. return (int) hash;
  144. }
  145.  
  146. public static long hash(long v) {
  147. long hash = v;
  148. long h = hash;
  149.  
  150. switch ((int) hash & 3) {
  151. case 3:
  152. hash += h;
  153. hash ^= hash << 32;
  154. hash ^= h << 36;
  155. hash += hash >> 22;
  156. break;
  157. case 2:
  158. hash += h;
  159. hash ^= hash << 22;
  160. hash += hash >> 34;
  161. break;
  162. case 1:
  163. hash += h;
  164. hash ^= hash << 20;
  165. hash += hash >> 2;
  166. }
  167. hash ^= hash << 6;
  168. hash += hash >> 10;
  169. hash ^= hash << 8;
  170. hash += hash >> 34;
  171. hash ^= hash << 50;
  172. hash += hash >> 12;
  173. return hash;
  174. }
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement