#ifndef r_texture_h
#define r_texture_h

#include <math.h>
#include "plugin.h"

#define HASHVEC(x,y,z) hashvectf+3*hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255]
#define rand_map(x,y,z) hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255]
#define s_curve(t) ( (t) * (t) * (3. - 2. * (t)) )

unsigned char hash[256]= {
 198, 12, 146, 95, 44, 18, 240, 28, 151, 32, 45, 20, 30, 23, 141, 248,
 168, 254, 178, 85, 92, 216, 236, 175, 47, 88, 67, 136, 234, 1, 72, 106,
 79, 220, 24, 171, 26, 224, 128, 137, 223, 16, 105, 195, 231, 183, 29,
 132, 241, 122, 252, 135, 5, 181, 130, 213, 49, 204, 70, 176, 144, 35, 
 64, 104, 19, 39, 46, 13, 246, 233, 9, 177, 31, 61, 154, 117, 129, 75,
 139, 118, 68, 42, 207, 86, 112, 27, 158, 8, 247, 250, 109, 163, 242, 
 52, 160, 164, 43, 83, 62, 190, 57, 155, 169, 98, 6, 51, 38, 150, 80,
 84, 114, 14, 253, 194, 4, 138, 101, 25, 60, 97, 167, 188, 148, 209, 
 77, 192, 131, 227, 36, 191, 237, 76, 214, 17, 251, 81, 71, 123, 119,
 232, 0, 244, 87, 53, 66, 126, 187, 110, 107, 2, 212, 93, 74, 211, 249,
 63, 102, 113, 255, 11, 173, 197, 166, 157, 226, 124, 90, 199, 59, 10, 
 100, 140, 89, 208, 221, 37, 33, 230, 121, 174, 189, 165, 149, 34, 179,
 15, 108, 40, 55, 91, 7, 200, 147, 120, 134, 56, 184, 133, 115, 202, 245,
 94, 82, 152, 116, 143, 210, 206, 145, 203, 193, 127, 180, 125, 22, 159, 
 142, 156, 219, 111, 99, 217, 96, 41, 162, 228, 3, 161, 58, 229, 153, 235, 
 215, 54, 205, 50, 218, 103, 69, 21, 48, 186, 170, 73, 65, 222, 238, 225, 
 78, 172, 185, 196, 182, 239, 201, 243
};

float hashvectf[256 * 3] = {
-0.382332, 0.045987, 0.412422,
0.322819, -0.523555, 0.155692,
-0.599637, 0.610314, 0.204491,
-0.326772, 0.183249, 0.170122,
0.137437, 0.159912, 0.346638,
0.012269, -0.149943, -0.247321,
0.421695, -0.031413, 0.222260,
0.269062, 0.312575, -0.166291,
-0.749370, -0.184944, 0.331976,
0.029522, 0.484716, 0.374884,
0.651325, 0.000000, 0.325664,
0.237639, -0.077213, 0.000000,
-0.599967, -0.599965, 0.000000,
-0.106802, 0.128980, 0.262476,
0.539146, -0.540820, -0.294115,
-0.402260, -0.235177, 0.513393,
-0.047496, -0.238059, -0.110230,
-0.041510, 0.047293, 0.083020,
0.031514, -0.065262, -0.051344,
0.036846, 0.514855, -0.309666,
0.312743, -0.159270, -0.225656,
0.473331, -0.343894, 0.361597,
-0.352909, 0.079702, -0.477326,
-0.180476, 0.212372, 0.185283,
-0.080332, 0.006545, 0.049649,
-0.337633, 0.364485, -0.607989,
-0.179383, 0.380025, -0.126611,
0.229949, -0.167068, 0.789544,
-0.879327, 0.000000, -0.104328,
0.061701, 0.558347, 0.643778,
-0.016567, -0.008710, -0.026806,
0.036742, -0.082902, -0.210578,
-0.686211, 0.498557, 0.205545,
0.050530, -0.184377, -0.101060,
-0.396777, 0.114284, 0.142954,
-0.399710, -0.370211, 0.799427,
0.010625, -0.360047, -0.285405,
-0.575730, 0.456870, 0.222734,
0.564252, 0.774509, -0.124628,
-0.175417, -0.057550, 0.049107,
0.126588, 0.389595, -0.119535,
-0.006558, -0.190696, 0.038741,
0.090039, -0.048335, -0.180079,
-0.043774, 0.029059, -0.011331,
0.073884, -0.145004, 0.000000,
-0.488167, -0.489682, 0.266305,
-0.048211, -0.254391, -0.078009,
0.301849, 0.074496, -0.133721,
-0.378882, 0.449358, -0.252802,
-0.026044, 0.080153, 0.069205,
-0.055610, -0.107745, 0.073953,
0.022285, 0.000000, 0.321538,
-0.000819, 0.286642, -0.076246,
0.042583, 0.058611, 0.000000,
-0.454821, 0.260599, 0.665373,
0.085960, -0.012420, -0.292721,
-0.083830, -0.359350, 0.107285,
-0.163418, 0.118730, -0.878918,
-0.215777, -0.389136, -0.211051,
-0.307529, 0.000000, -0.322809,
-0.623562, 0.172665, -0.577490,
-0.424905, 0.082658, -0.205316,
0.083868, 0.258113, -0.753892,
-0.319969, 0.000000, -0.725878,
-0.006615, 0.004806, -0.072567,
0.464495, -0.077344, 0.351270,
-0.016793, -0.093071, -0.166656,
0.060751, 0.840006, -0.362233,
-0.198387, 0.225023, 0.936188,
-0.444758, -0.115140, -0.354659,
0.014497, -0.029373, -0.046912,
0.526206, -0.445624, -0.362435,
-0.231729, -0.289542, 0.182363,
0.125520, -0.057606, -0.044101,
0.055588, -0.049504, -0.082013,
-0.845759, -0.470834, -0.068169,
0.082669, 0.041471, 0.013118,
0.259258, 0.157987, 0.511734,
0.276396, -0.134263, -0.265539,
0.500715, 0.231015, 0.445317,
-0.311734, 0.103178, 0.137202,
0.011978, -0.152683, -0.413649,
-0.013775, 0.217392, -0.341425,
0.287605, -0.131299, 0.022249,
-0.023086, 0.000000, -0.081268,
0.059899, 0.004714, 0.000000,
-0.284805, -0.603364, -0.201020,
0.140391, 0.316763, -0.804606,
0.426147, -0.103548, 0.111007,
-0.276499, -0.264919, -0.271293,
0.821277, 0.124308, 0.455800,
-0.632242, -0.694367, 0.167233,
0.013052, 0.025603, 0.018478,
0.070566, -0.104252, -0.063714,
0.028317, 0.023133, 0.034385,
0.501435, -0.430703, -0.475005,
-0.174560, -0.766047, 0.349119,
-0.164142, 0.056665, -0.388170,
-0.763245, 0.388889, 0.000000,
0.444891, -0.079174, 0.390493,
0.159980, -0.057249, 0.134630,
0.163417, -0.229607, -0.192898,
0.288537, -0.390402, -0.284583,
-0.075388, -0.805658, 0.565244,
-0.193679, -0.078991, 0.024717,
-0.045931, 0.111235, -0.074319,
-0.665672, -0.344944, 0.411413,
-0.096546, -0.583653, -0.324629,
0.407930, 0.104540, 0.660048,
-0.820568, 0.267792, 0.112261,
0.663010, -0.575374, -0.320677,
-0.573242, 0.416483, -0.437923,
0.029031, 0.562818, -0.514251,
-0.688641, 0.311200, 0.134575,
-0.113951, -0.185842, 0.588785,
0.079390, -0.032140, 0.023769,
0.221999, -0.259927, 0.000000,
0.816506, 0.454549, 0.065812,
0.003058, 0.003097, 0.000617,
0.149211, 0.008463, -0.140542,
0.353697, -0.301407, -0.286977,
-0.444848, 0.388932, -0.262564,
0.109570, -0.237067, 0.383215,
-0.843997, -0.164186, -0.407824,
0.748646, -0.176676, 0.310143,
0.017268, 0.448852, 0.085881,
0.001312, 0.013876, 0.043496,
-0.031838, -0.277795, 0.019677,
0.037472, -0.974004, 0.186361,
-0.596817, 0.433611, -0.329135,
-0.103800, 0.016461, -0.067573,
0.602512, 0.602510, 0.000000,
0.055517, 0.517075, -0.111035,
-0.193866, 0.048150, 0.028228,
-0.073225, -0.070150, 0.178692,
0.231196, -0.405436, 0.534878,
-0.008113, -0.024969, -0.092419,
-0.514870, -0.415516, -0.472159,
0.483225, 0.254046, 0.781881,
-0.016453, 0.123169, -0.312721,
-0.182725, -0.214054, -0.760135,
0.574751, -0.381369, -0.209033,
-0.370622, 0.394840, 0.540370,
-0.221661, -0.523415, -0.207639,
0.165177, -0.508353, -0.330354,
0.292668, 0.900738, 0.000000,
0.093909, 0.023324, -0.013674,
-0.413931, -0.048747, -0.189258,
-0.045809, -0.386021, 0.313923,
0.457278, 0.591863, 0.592619,
-0.361923, 0.087650, 0.390406,
0.093210, 0.250343, -0.057607,
0.256967, 0.037128, -0.875059,
-0.258041, 0.382945, 0.640064,
0.004503, -0.005276, 0.018734,
-0.124908, -0.203830, 0.000000,
-0.165268, 0.240234, -0.299769,
0.721980, 0.396683, 0.175990,
0.528949, -0.214708, 0.342476,
0.479550, -0.122894, 0.775932,
-0.030996, 0.000000, 0.134868,
-0.014594, 0.044915, -0.017316,
0.580160, -0.498274, 0.471095,
0.160296, 0.142754, -0.236497,
0.074791, -0.142261, -0.046224,
0.412773, -0.479527, -0.255110,
-0.228631, 0.399995, 0.164699,
0.299747, -0.535610, -0.495665,
-0.039875, -0.028970, 0.059480,
-0.259657, 0.188650, 0.336903,
-0.135250, -0.416248, 0.472116,
-0.127893, 0.074129, -0.343279,
-0.005685, 0.009164, -0.001274,
-0.691049, -0.350751, 0.298473,
-0.031537, 0.217033, 0.063074,
-0.186958, 0.404504, -0.653873,
0.041271, -0.576689, -0.346857,
-0.132702, -0.041688, 0.095206,
0.249581, 0.181331, 0.332778,
0.046968, -0.034124, 0.515215,
-0.576599, -0.072440, 0.304896,
-0.494652, -0.673044, 0.349003,
0.763427, 0.277402, 0.164917,
-0.131499, 0.064191, -0.288233,
0.347980, 0.096356, 0.322270,
-0.131006, 0.137525, 0.477995,
0.194294, 0.112615, 0.521505,
0.173785, 0.070542, 0.112520,
0.143387, 0.129961, -0.245641,
0.545331, -0.273569, 0.086535,
-0.067099, 0.048750, -0.120032,
0.309317, 0.224729, -0.532433,
0.217197, 0.157801, -0.609051,
0.032277, -0.002693, -0.004582,
0.016443, -0.005291, 0.004595,
0.065510, -0.534217, 0.255287,
0.385232, -0.617460, -0.201973,
0.049956, 0.036295, -0.217366,
-0.071771, -0.155923, -0.077943,
0.396951, -0.057680, -0.574478,
-0.188498, 0.053955, 0.271770,
0.490110, 0.581275, 0.327016,
-0.002596, -0.003844, 0.000942,
-0.276486, 0.352783, 0.026408,
-0.067877, 0.614233, -0.708215,
-0.014551, -0.095078, 0.058666,
-0.552212, 0.696821, 0.296471,
0.029568, -0.091002, 0.265439,
0.740368, -0.154013, -0.270329,
-0.115748, 0.135523, 0.000000,
0.423776, 0.370509, 0.250127,
-0.248043, -0.484951, -0.209789,
-0.000314, -0.057460, -0.024009,
0.273355, -0.259453, 0.137294,
-0.037477, -0.115346, -0.575826,
0.274724, 0.142359, -0.169791,
0.037665, -0.027365, -0.031991,
-0.359330, 0.636097, 0.051412,
0.101262, 0.209703, -0.164983,
-0.200361, -0.278973, -0.143513,
-0.133635, 0.166975, 0.105166,
-0.272142, -0.197720, 0.353101,
0.520612, 0.708366, -0.367319,
0.273803, -0.126571, 0.369126,
-0.034668, -0.165782, -0.214985,
0.167786, -0.905754, -0.335573,
0.741254, 0.239782, 0.101324,
0.673682, 0.276876, -0.184366,
-0.079911, 0.058058, 0.468966,
-0.090320, -0.107120, -0.060264,
-0.476929, -0.487660, -0.632836,
0.020207, 0.574117, -0.040414,
-0.503039, 0.365478, -0.510581,
0.115311, 0.130793, -0.544152,
0.056282, 0.794572, -0.112563,
0.488661, 0.497362, -0.166646,
-0.215566, 0.385861, 0.540876,
0.795336, -0.403683, -0.343516,
-0.234981, 0.723209, -0.380219,
-0.045123, 0.306946, 0.287834,
0.031085, 0.083707, -0.006290,
0.311298, -0.226170, 0.171675,
-0.137457, 0.224179, 0.710243,
-0.279656, 0.499711, 0.462443,
0.831447, 0.131686, 0.000000,
-0.309519, -0.109618, 0.619045,
0.159594, 0.046698, -0.131755,
-0.171930, 0.147663, -0.139609,
-0.261018, -0.127415, -0.572127,
-0.181165, -0.557579, -0.707514,
-0.709104, 0.170238, 0.000000,
0.012680, 0.039026, 0.077985,
-0.316095, -0.038020, 0.340972,
0.167454, 0.515380, 0.495246,
0.126888, 0.136979, 0.228492,
0.214834, 0.456259, -0.107739
 };


float fixed_rand(int seed,float x, float y, float z)
{
	/* generate int keys from floats. */
	unsigned char keyx,keyy,keyz;

	keyx = ((unsigned char *)(&x))[0] + ((unsigned char *)(&x))[1] + 
		((unsigned char *)(&x))[2] + ((unsigned char *)(&x))[3];
	keyy = ((unsigned char *)(&y))[0] + ((unsigned char *)(&y))[1] + 
		((unsigned char *)(&y))[2] + ((unsigned char *)(&y))[3];
	keyz = ((unsigned char *)(&z))[0] + ((unsigned char *)(&z))[1] + 
		((unsigned char *)(&z))[2] + ((unsigned char *)(&z))[3];
	return (float) (hash[(hash[(hash[(seed + keyx) & 255] + keyy) & 255] + 
		keyz) & 255]) / 256.0;
}

void turb(float noisesize, float xc, float yc, float zc, float *vec, int seed)
{
	float cn1, cn2, cn3, cn4, cn5, cn6, i, *h;
	float x,y,z,ox, oy, oz, jx, jy, jz;
	int ix, iy, iz,b00, b01, b10, b11, b20, b21;
	int kx,ky,kz;

	vec[0] = vec[1] = vec[2] = 0;

	if(noisesize==0.0) 
	 return;


	x= (1.0+xc)/noisesize;
	y= (1.0+yc)/noisesize;
	z= (1.0+zc)/noisesize;


	ox= (x- (ix= (int)floorf(x)) );
	oy= (y- (iy= (int)floorf(y)) );
	oz= (z- (iz= (int)floorf(z)) );

	jx= ox-1;
	jy= oy-1;
	jz= oz-1;

	kx = ix + 1;
	ky = iy + 1;
	kz = iz + 1;

	cn1=ox*ox; cn2=oy*oy; cn3=oz*oz;
	cn4=jx*jx; cn5=jy*jy; cn6=jz*jz;

	cn1= 1.0-3.0*cn1+2.0*cn1*ox;
	cn2= 1.0-3.0*cn2+2.0*cn2*oy;
	cn3= 1.0-3.0*cn3+2.0*cn3*oz;
	cn4= 1.0-3.0*cn4-2.0*cn4*jx;
	cn5= 1.0-3.0*cn5-2.0*cn5*jy;
	cn6= 1.0-3.0*cn6-2.0*cn6*jz;

	b00= hash[ (hash[ix & 255]+ iy) & 255];
	b10= hash[ (hash[kx & 255]+iy) & 255];
	b01= hash[ (hash[ix & 255]+ ky) & 255];
	b11= hash[ (hash[kx & 255]+ ky) & 255];

	b20=iz & 255; b21= kz & 255;

	i= (cn1*cn2*cn3);
	h=hashvectf+ 3*hash[(b20+b00+ seed) & 255];
	vec[0] += h[0]*ox*i;
	vec[1] += h[1]*oy*i;
	vec[2] += h[2]*oz*i;

	
	i= (cn1*cn2*cn6);
		h=hashvectf+ 3*hash[(b21+b00+ seed) & 255];
	vec[0] += h[0]*ox*i;
	vec[1] += h[1]*oy*i;
	vec[2] += h[2]*jz*i;

	i= (cn1*cn5*cn3);
		h=hashvectf+ 3*hash[(b20+b01+ seed) & 255];
	vec[0] += h[0]*ox*i;
	vec[1] += h[1]*jy*i;
	vec[2] += h[2]*oz*i;

	i= (cn1*cn5*cn6);
		h=hashvectf+ 3*hash[(b21+b01+ seed) & 255];
	vec[0] += h[0]*ox*i;
	vec[1] += h[1]*jy*i;
	vec[2] += h[2]*jz*i;

	i= cn4*cn2*cn3;
		h=hashvectf+ 3*hash[(b20+b10+ seed) & 255];
	vec[0] += h[0]*jx*i;
	vec[1] += h[1]*oy*i;
	vec[2] += h[2]*oz*i;

	i= cn4*cn2*cn6;
		h=hashvectf+ 3*hash[(b21+b10+ seed) & 255];
	vec[0] += h[0]*jx*i;
	vec[1] += h[1]*oy*i;
	vec[2] += h[2]*jz*i;

	i= cn4*cn5*cn3;
		h=hashvectf+ 3*hash[(b20+b11+ seed) & 255];
	vec[0] += h[0]*jx*i;
	vec[1] += h[1]*jy*i;
	vec[2] += h[2]*oz*i;

	i= (cn4*cn5*cn6);
		h=hashvectf+ 3*hash[(b21+b11 + seed) & 255];
	vec[0] += h[0]*jx*i;
	vec[1] += h[1]*jy*i;
	vec[2] += h[2]*jz*i;
}


void recursive_turb(float noisesize, float falloff, int hard, float x, float y, float z, float *vec, int nr, int seed)
{
	float d= 1.0, div = 0.0;
	float tvec[3];
	float total;	
	vec[0] = vec[1] = vec[2] = 0;
	while (nr >= 0)
	{
		turb(noisesize *d, x,y,z,tvec,seed);

		if (hard)
		{
			total = tvec[0] + tvec[1] + tvec[2];
			if (total < 0.0)
				total -= 2.0;
			else
				total += 2.0;
			tvec[0] *= total;
			tvec[1] *= total;
			tvec[2] *= total;
		}
		vec[0] += tvec[0] * d;
		vec[1] += tvec[1] * d;
		vec[2] += tvec[2] * d;

		div+= d;
		d *= falloff;
		falloff = 0.61; /* set to normal falloff after first iteration*/
		nr --;
	}
	vec[0] /= div;
	vec[1] /= div;
	vec[2] /= div;
}


void vec_copy(float *va, float *vb)
{
	va[0] = vb[0];
	va[1] = vb[1];
	va[2] = vb[2];
}
float vec_len(float *v)
{
	return fsqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
}
void vec_add(float *v,float *va, float *vb)
{
	v[0] = va[0] + vb[0];
	v[1] = va[1] + vb[1];
	v[2] = va[2] + vb[2];
}
void vec_sub(float *v,float *va, float *vb)
{
	v[0] = va[0] - vb[0];
	v[1] = va[1] - vb[1];
	v[2] = va[2] - vb[2];
}

void crossp(float *v,float *va, float *vb)
{
	v[0] = va[1] * vb[2] - va[2] * vb[1];
	v[1] = va[2] * vb[0] - va[0] * vb[2];
	v[2] = va[0] * vb[1] - va[1] * vb[0];
}

void vec_normalize(float *v)
{
	float li;
	double l = vec_len(v);
	if (l < 0.0000000001)
		l = 0.0000000001;
	li = 1.0 / l;
	v[0] *= li;
	v[1] *= li;
	v[2] *= li;
}

void point_turbulance(float noise_size, float falloff, int hard, float x,
	float y, float z, float *vec, int depth, int seed)
{
	recursive_turb(noise_size, falloff, hard, x, y, z,vec,depth,seed);
}
#endif
