dbf-halloween2015

annotate src/pnoise.cc @ 0:50683c78264e

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 01 Nov 2015 00:09:12 +0200
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 scalar_t 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 scalar_t 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 period)
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, period);
nuclear@0 109 setup_p(y, by0, by1, ry0, ry1, period);
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 pfbm2(float x, float y, int octaves, int period)
nuclear@0 139 {
nuclear@0 140 float res = 0.0;
nuclear@0 141 float s = 1.0;
nuclear@0 142
nuclear@0 143 for(int i=0; i<octaves; i++) {
nuclear@0 144 float v = pnoise2(x * s, y * s, period);
nuclear@0 145 res += v / s;
nuclear@0 146 s *= 2.0;
nuclear@0 147 period *= 2;
nuclear@0 148 }
nuclear@0 149
nuclear@0 150 return res;
nuclear@0 151 }
nuclear@0 152
nuclear@0 153 float pturbulence2(float x, float y, int octaves, int period)
nuclear@0 154 {
nuclear@0 155 float res = 0.0;
nuclear@0 156 float s = 1.0;
nuclear@0 157
nuclear@0 158 for(int i=0; i<octaves; i++) {
nuclear@0 159 float v = fabs(pnoise2(x * s, y * s, period));
nuclear@0 160 res += v / s;
nuclear@0 161 s *= 2.0;
nuclear@0 162 period *= 2;
nuclear@0 163 }
nuclear@0 164
nuclear@0 165 return res;
nuclear@0 166 }