ld33_umonster
diff src/pnoise.cc @ 0:4a6683050e29
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 22 Aug 2015 07:15:00 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/pnoise.cc Sat Aug 22 07:15:00 2015 +0300 1.3 @@ -0,0 +1,149 @@ 1.4 +#include <stdlib.h> 1.5 +#include "pnoise.h" 1.6 +#include "vmath/vmath.h" 1.7 + 1.8 +#define B 0x100 1.9 +#define BM 0xff 1.10 +#define N 0x1000 1.11 +#define NP 12 1.12 +#define NM 0xfff 1.13 + 1.14 +#define s_curve(t) ((t) * (t) * (3.0f - 2.0f * (t))) 1.15 +#define setup(elem, b0, b1, r0, r1) \ 1.16 + do { \ 1.17 + float t = elem + N; \ 1.18 + b0 = ((int)t) & BM; \ 1.19 + b1 = (b0 + 1) & BM; \ 1.20 + r0 = t - (int)t; \ 1.21 + r1 = r0 - 1.0f; \ 1.22 + } while(0) 1.23 + 1.24 +#define setup_p(elem, b0, b1, r0, r1, p) \ 1.25 + do { \ 1.26 + float t = elem + N; \ 1.27 + b0 = (((int)t) & BM) % p; \ 1.28 + b1 = ((b0 + 1) & BM) % p; \ 1.29 + r0 = t - (int)t; \ 1.30 + r1 = r0 - 1.0f; \ 1.31 + } while(0) 1.32 + 1.33 +static int perm[B + B + 2]; 1.34 +static vec2_t grad2[B + B + 2]; 1.35 +static bool tables_valid; 1.36 + 1.37 +static void init_noise() 1.38 +{ 1.39 + for(int i=0; i<B; i++) { 1.40 + perm[i] = i; 1.41 + 1.42 + grad2[i].x = (float)((rand() % (B + B)) - B) / B; 1.43 + grad2[i].y = (float)((rand() % (B + B)) - B) / B; 1.44 + grad2[i] = v2_normalize(grad2[i]); 1.45 + } 1.46 + 1.47 + for(int i=0; i<B; i++) { 1.48 + int rand_idx = rand() % B; 1.49 + 1.50 + int tmp = perm[i]; 1.51 + perm[i] = perm[rand_idx]; 1.52 + perm[rand_idx] = tmp; 1.53 + } 1.54 + 1.55 + for(int i=0; i<B+2; i++) { 1.56 + perm[B + i] = perm[i]; 1.57 + grad2[B + i] = grad2[i]; 1.58 + } 1.59 +} 1.60 + 1.61 +#define lerp(a, b, t) ((a) + ((b) - (a)) * t) 1.62 + 1.63 +float dbg_noise2(float x, float y) 1.64 +{ 1.65 + if(!tables_valid) { 1.66 + init_noise(); 1.67 + tables_valid = true; 1.68 + } 1.69 + 1.70 + int bx0, bx1, by0, by1; 1.71 + float rx0, rx1, ry0, ry1; 1.72 + setup(x, bx0, bx1, rx0, rx1); 1.73 + setup(y, by0, by1, ry0, ry1); 1.74 + 1.75 + int i = perm[bx0]; 1.76 + int j = perm[bx1]; 1.77 + 1.78 + int b00 = perm[i + by0]; 1.79 + int b10 = perm[j + by0]; 1.80 + int b01 = perm[i + by1]; 1.81 + int b11 = perm[j + by1]; 1.82 + 1.83 + float sx = s_curve(rx0); 1.84 + float sy = s_curve(ry0); 1.85 + 1.86 + vec2_t g00 = grad2[b00]; 1.87 + vec2_t g10 = grad2[b10]; 1.88 + vec2_t g01 = grad2[b01]; 1.89 + vec2_t g11 = grad2[b11]; 1.90 + 1.91 + float u = g00.x * rx0 + g00.y * ry0; 1.92 + float v = g10.x * rx1 + g10.y * ry0; 1.93 + float a = lerp(u, v, sx); 1.94 + 1.95 + u = g01.x * rx0 + g01.y * ry1; 1.96 + v = g11.x * rx1 + g11.y * ry1; 1.97 + float b = lerp(u, v, sx); 1.98 + 1.99 + return lerp(a, b, sy); 1.100 +} 1.101 + 1.102 +float pnoise2(float x, float y, int periodx, int periody) 1.103 +{ 1.104 + if(!tables_valid) { 1.105 + init_noise(); 1.106 + tables_valid = true; 1.107 + } 1.108 + 1.109 + int bx0, bx1, by0, by1; 1.110 + float rx0, rx1, ry0, ry1; 1.111 + setup_p(x, bx0, bx1, rx0, rx1, periodx); 1.112 + setup_p(y, by0, by1, ry0, ry1, periody); 1.113 + 1.114 + int i = perm[bx0]; 1.115 + int j = perm[bx1]; 1.116 + 1.117 + int b00 = perm[i + by0]; 1.118 + int b10 = perm[j + by0]; 1.119 + int b01 = perm[i + by1]; 1.120 + int b11 = perm[j + by1]; 1.121 + 1.122 + float sx = s_curve(rx0); 1.123 + float sy = s_curve(ry0); 1.124 + 1.125 + vec2_t g00 = grad2[b00]; 1.126 + vec2_t g10 = grad2[b10]; 1.127 + vec2_t g01 = grad2[b01]; 1.128 + vec2_t g11 = grad2[b11]; 1.129 + 1.130 + float u = g00.x * rx0 + g00.y * ry0; 1.131 + float v = g10.x * rx1 + g10.y * ry0; 1.132 + float a = lerp(u, v, sx); 1.133 + 1.134 + u = g01.x * rx0 + g01.y * ry1; 1.135 + v = g11.x * rx1 + g11.y * ry1; 1.136 + float b = lerp(u, v, sx); 1.137 + 1.138 + return lerp(a, b, sy); 1.139 +} 1.140 + 1.141 +float pturbulence2(float x, float y, int periodx, int periody, int octaves) 1.142 +{ 1.143 + int i; 1.144 + float res = 0.0f, freq = 1.0f; 1.145 + for(i=0; i<octaves; i++) { 1.146 + res += fabs(pnoise2(x * freq, y * freq, periodx, periody) / freq); 1.147 + freq *= 2.0f; 1.148 + periodx *= 2; 1.149 + periody *= 2; 1.150 + } 1.151 + return res; 1.152 +}