tavli

diff src/pnoise.cc @ 6:a0d30f6f20d4

- texture coordinate generation in class Mesh - wood texture
author John Tsiombikas <nuclear@member.fsf.org>
date Fri, 26 Jun 2015 04:22:06 +0300
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/pnoise.cc	Fri Jun 26 04:22:06 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 +}