tavli

annotate src/pnoise.cc @ 11:a8e26f163f99

poulia
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 27 Jun 2015 08:01:51 +0300
parents
children
rev   line source
nuclear@6 1 #include <stdlib.h>
nuclear@6 2 #include "pnoise.h"
nuclear@6 3 #include "vmath/vmath.h"
nuclear@6 4
nuclear@6 5 #define B 0x100
nuclear@6 6 #define BM 0xff
nuclear@6 7 #define N 0x1000
nuclear@6 8 #define NP 12
nuclear@6 9 #define NM 0xfff
nuclear@6 10
nuclear@6 11 #define s_curve(t) ((t) * (t) * (3.0f - 2.0f * (t)))
nuclear@6 12 #define setup(elem, b0, b1, r0, r1) \
nuclear@6 13 do { \
nuclear@6 14 float t = elem + N; \
nuclear@6 15 b0 = ((int)t) & BM; \
nuclear@6 16 b1 = (b0 + 1) & BM; \
nuclear@6 17 r0 = t - (int)t; \
nuclear@6 18 r1 = r0 - 1.0f; \
nuclear@6 19 } while(0)
nuclear@6 20
nuclear@6 21 #define setup_p(elem, b0, b1, r0, r1, p) \
nuclear@6 22 do { \
nuclear@6 23 float t = elem + N; \
nuclear@6 24 b0 = (((int)t) & BM) % p; \
nuclear@6 25 b1 = ((b0 + 1) & BM) % p; \
nuclear@6 26 r0 = t - (int)t; \
nuclear@6 27 r1 = r0 - 1.0f; \
nuclear@6 28 } while(0)
nuclear@6 29
nuclear@6 30 static int perm[B + B + 2];
nuclear@6 31 static vec2_t grad2[B + B + 2];
nuclear@6 32 static bool tables_valid;
nuclear@6 33
nuclear@6 34 static void init_noise()
nuclear@6 35 {
nuclear@6 36 for(int i=0; i<B; i++) {
nuclear@6 37 perm[i] = i;
nuclear@6 38
nuclear@6 39 grad2[i].x = (float)((rand() % (B + B)) - B) / B;
nuclear@6 40 grad2[i].y = (float)((rand() % (B + B)) - B) / B;
nuclear@6 41 grad2[i] = v2_normalize(grad2[i]);
nuclear@6 42 }
nuclear@6 43
nuclear@6 44 for(int i=0; i<B; i++) {
nuclear@6 45 int rand_idx = rand() % B;
nuclear@6 46
nuclear@6 47 int tmp = perm[i];
nuclear@6 48 perm[i] = perm[rand_idx];
nuclear@6 49 perm[rand_idx] = tmp;
nuclear@6 50 }
nuclear@6 51
nuclear@6 52 for(int i=0; i<B+2; i++) {
nuclear@6 53 perm[B + i] = perm[i];
nuclear@6 54 grad2[B + i] = grad2[i];
nuclear@6 55 }
nuclear@6 56 }
nuclear@6 57
nuclear@6 58 #define lerp(a, b, t) ((a) + ((b) - (a)) * t)
nuclear@6 59
nuclear@6 60 float dbg_noise2(float x, float y)
nuclear@6 61 {
nuclear@6 62 if(!tables_valid) {
nuclear@6 63 init_noise();
nuclear@6 64 tables_valid = true;
nuclear@6 65 }
nuclear@6 66
nuclear@6 67 int bx0, bx1, by0, by1;
nuclear@6 68 float rx0, rx1, ry0, ry1;
nuclear@6 69 setup(x, bx0, bx1, rx0, rx1);
nuclear@6 70 setup(y, by0, by1, ry0, ry1);
nuclear@6 71
nuclear@6 72 int i = perm[bx0];
nuclear@6 73 int j = perm[bx1];
nuclear@6 74
nuclear@6 75 int b00 = perm[i + by0];
nuclear@6 76 int b10 = perm[j + by0];
nuclear@6 77 int b01 = perm[i + by1];
nuclear@6 78 int b11 = perm[j + by1];
nuclear@6 79
nuclear@6 80 float sx = s_curve(rx0);
nuclear@6 81 float sy = s_curve(ry0);
nuclear@6 82
nuclear@6 83 vec2_t g00 = grad2[b00];
nuclear@6 84 vec2_t g10 = grad2[b10];
nuclear@6 85 vec2_t g01 = grad2[b01];
nuclear@6 86 vec2_t g11 = grad2[b11];
nuclear@6 87
nuclear@6 88 float u = g00.x * rx0 + g00.y * ry0;
nuclear@6 89 float v = g10.x * rx1 + g10.y * ry0;
nuclear@6 90 float a = lerp(u, v, sx);
nuclear@6 91
nuclear@6 92 u = g01.x * rx0 + g01.y * ry1;
nuclear@6 93 v = g11.x * rx1 + g11.y * ry1;
nuclear@6 94 float b = lerp(u, v, sx);
nuclear@6 95
nuclear@6 96 return lerp(a, b, sy);
nuclear@6 97 }
nuclear@6 98
nuclear@6 99 float pnoise2(float x, float y, int periodx, int periody)
nuclear@6 100 {
nuclear@6 101 if(!tables_valid) {
nuclear@6 102 init_noise();
nuclear@6 103 tables_valid = true;
nuclear@6 104 }
nuclear@6 105
nuclear@6 106 int bx0, bx1, by0, by1;
nuclear@6 107 float rx0, rx1, ry0, ry1;
nuclear@6 108 setup_p(x, bx0, bx1, rx0, rx1, periodx);
nuclear@6 109 setup_p(y, by0, by1, ry0, ry1, periody);
nuclear@6 110
nuclear@6 111 int i = perm[bx0];
nuclear@6 112 int j = perm[bx1];
nuclear@6 113
nuclear@6 114 int b00 = perm[i + by0];
nuclear@6 115 int b10 = perm[j + by0];
nuclear@6 116 int b01 = perm[i + by1];
nuclear@6 117 int b11 = perm[j + by1];
nuclear@6 118
nuclear@6 119 float sx = s_curve(rx0);
nuclear@6 120 float sy = s_curve(ry0);
nuclear@6 121
nuclear@6 122 vec2_t g00 = grad2[b00];
nuclear@6 123 vec2_t g10 = grad2[b10];
nuclear@6 124 vec2_t g01 = grad2[b01];
nuclear@6 125 vec2_t g11 = grad2[b11];
nuclear@6 126
nuclear@6 127 float u = g00.x * rx0 + g00.y * ry0;
nuclear@6 128 float v = g10.x * rx1 + g10.y * ry0;
nuclear@6 129 float a = lerp(u, v, sx);
nuclear@6 130
nuclear@6 131 u = g01.x * rx0 + g01.y * ry1;
nuclear@6 132 v = g11.x * rx1 + g11.y * ry1;
nuclear@6 133 float b = lerp(u, v, sx);
nuclear@6 134
nuclear@6 135 return lerp(a, b, sy);
nuclear@6 136 }
nuclear@6 137
nuclear@6 138 float pturbulence2(float x, float y, int periodx, int periody, int octaves)
nuclear@6 139 {
nuclear@6 140 int i;
nuclear@6 141 float res = 0.0f, freq = 1.0f;
nuclear@6 142 for(i=0; i<octaves; i++) {
nuclear@6 143 res += fabs(pnoise2(x * freq, y * freq, periodx, periody) / freq);
nuclear@6 144 freq *= 2.0f;
nuclear@6 145 periodx *= 2;
nuclear@6 146 periody *= 2;
nuclear@6 147 }
nuclear@6 148 return res;
nuclear@6 149 }