Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package org.scribble.scommon;
- import java.util.Arrays;
- public class OlsenNoise2D {
- public static void convolve(int[] pixels, int offset, int stride, int x, int y, int width, int height, int[][] matrix, int parts) {
- int startIndex = x + (y * stride);
- int lastIndex = (x + width - 1) + ((y + height - 1) * stride);
- int x_pos = x;
- int y_pos = y;
- int indexInc = 1;
- int yinc = 0;
- int xinc = 1;
- for (int i = 0, s = width + height; i < s; i++) {
- if (i == width) {
- indexInc = stride;
- yinc = 1;
- xinc = 0;
- }
- int x_counter = x_pos;
- int index = startIndex;
- while (x_counter >= x && index <= lastIndex) {
- pixels[offset + index] = convolve(pixels, stride, offset + index, matrix, parts);
- x_counter--;
- index += stride - 1;
- }
- startIndex += indexInc;
- x_pos += xinc;
- y_pos += yinc;
- }
- }
- private static int crimp(int color) {
- return (color >= 0xFF) ? 0xFF : (color < 0) ? 0 : color;
- }
- private static int convolve(int[] pixels, int stride, int index, int[][] matrix, int parts) {
- int redSum = 0;
- int greenSum = 0;
- int blueSum = 0;
- int pixel, factor;
- for (int j = 0, m = matrix.length; j < m; j++, index++) {
- for (int k = 0, n = matrix[j].length, q = index; k < n; k++, q += stride) {
- pixel = pixels[q];
- factor = matrix[j][k];
- redSum += factor * ((pixel >> 16) & 0xFF);
- greenSum += factor * ((pixel >> 8) & 0xFF);
- blueSum += factor * ((pixel) & 0xFF);
- }
- }
- return 0xFF000000 | ((crimp(redSum / parts) << 16) | (crimp(greenSum / parts) << 8) | (crimp(blueSum / parts)));
- }
- //occupies same footprint
- 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) {
- int index = (y_within_scope * stride);
- for (int k = y_within_scope, n = y_within_scope + height - 1; k <= n; k++, index += stride) {
- for (int j = x_within_scope, m = x_within_scope + width - 1; j <= m; j++) {
- int current = index + j;
- pixels[current] += (hashrandom(x_within_field + j, y_within_field + k, iteration) & (1 << (7 - iteration)));
- }
- }
- }
- //requires half the height and width be good.
- private void applyScale(int[] pixels, int stride, int x_within_scope, int y_within_scope, int width, int height) {
- int index = (y_within_scope + height - 1) * stride;
- for (int k = y_within_scope, n = y_within_scope + height - 1; k <= n; n--, index -= stride) {
- for (int j = x_within_scope, m = x_within_scope + width - 1; j <= m; m--) {
- int current = index + m;
- int lower = ((n / 2) * stride) + (m / 2);
- pixels[current] = pixels[lower];
- }
- }
- }
- //requires width + 1 valid, height + 1
- private static final int[][] blur2x2 = new int[][]{
- {1, 1},
- {1, 1},
- };
- private void applyBlur(int[] pixels, int stride, int x_within_scope, int y_within_scope, int width, int height) {
- convolve(pixels, 0, stride, x_within_scope, y_within_scope, width, height, blur2x2, 4);
- }
- //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.
- public int getRequiredDim(int dim) {
- return (dim + 5) * 2;
- }
- private void trim(int[] pixels, int width, int height, int[] workingpixels, int workingstride) {
- for (int k = 0; k < height; k++) {
- for (int j = 0; j < width; j++) {
- int index = j + (k * width);
- int workingindex = j + (k * workingstride);
- pixels[index] = workingpixels[workingindex];
- }
- }
- }
- static final int maxiterations = 5;
- public void olsennoise(int[] pixels, int stride, int x, int y, int width, int height) {
- Arrays.fill(pixels, 0xFF000000);
- olsennoise(pixels, stride, x, y, 0, 0, width, height, maxiterations);
- }
- public void olsennoise(int[] pixels, int stride, int x_within_field, int y_within_field, int x_within_scope, int y_within_scope, int width, int height, int iteration) {
- if (iteration == 0) {
- applyNoise(pixels, stride, x_within_scope, y_within_scope, x_within_field, y_within_field, width, height, iteration);
- return;
- }
- x_within_scope = (x_within_field)&1;
- y_within_scope = (y_within_field)&1;
- int scopeX = (((x_within_field-1)+x_within_scope)/2);
- int scopeY = (((y_within_field-1)+y_within_scope)/2);
- int halfWidth = (width+1)/2;
- int halfHeight = (height+1)/2;
- int scopeWidth = (halfWidth) + ((width)&1) ;
- int scopeHeight = (halfHeight) + ((height)&1);
- olsennoise(pixels, stride, scopeX, scopeY, x_within_scope, y_within_scope, scopeWidth, scopeHeight, iteration - 1);
- scopeWidth -= 1;
- scopeHeight -= 1;
- //does not change position of x,y
- applyBlur(pixels, stride, scopeX, scopeY, scopeWidth, scopeHeight);
- scopeWidth *= 2;
- scopeHeight *= 2;
- scopeX *= 2;
- scopeY *= 2;
- applyScale(pixels, stride, scopeX, scopeY, scopeWidth, scopeHeight);
- //noise requires width, and height valid pixels
- applyNoise(pixels, stride, scopeX, scopeY, x_within_field, y_within_field, scopeWidth, scopeHeight, iteration);
- System.out.println(iteration);
- System.out.println(" " + scopeWidth + " == " + width + " && " + scopeHeight + " == " + height);
- }
- public static int hashrandom(int... elements) {
- long hash = 0;
- for (int i = 0; i < elements.length; i++) {
- hash ^= elements[i];
- hash = hash(hash);
- }
- return (int) hash;
- }
- public static long hash(long v) {
- long hash = v;
- long h = hash;
- switch ((int) hash & 3) {
- case 3:
- hash += h;
- hash ^= hash << 32;
- hash ^= h << 36;
- hash += hash >> 22;
- break;
- case 2:
- hash += h;
- hash ^= hash << 22;
- hash += hash >> 34;
- break;
- case 1:
- hash += h;
- hash ^= hash << 20;
- hash += hash >> 2;
- }
- hash ^= hash << 6;
- hash += hash >> 10;
- hash ^= hash << 8;
- hash += hash >> 34;
- hash ^= hash << 50;
- hash += hash >> 12;
- return hash;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement