ld33_umonster

annotate src/pnoise.cc @ 2:35349df5392d

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