#include "rsnoise.h" #include "rsgame.h" #ifdef RS_USE_C_LIBS #include #include #else #include "rs/rsplatform.h" #endif rs_perlin_conf_t rs_perlin_conf; void rs_perlin_configure(float freq, int octaves, float persistence, float seed, int tex_size) { rs_perlin_conf.freq = freq; rs_perlin_conf.octaves = octaves; rs_perlin_conf.persistence = persistence; rs_perlin_conf.seed = seed; rs_perlin_conf.tex_size = tex_size; rs_perlin_conf.period = (int) (0.1 + roundf(freq) ); // *tex_size }; float rs_noise(int x, int y) { // from here, http://www.cplusplus.com/forum/general/85758/ // koef. changed int n = x + y * 57 * 5; // no *2 n = (n << 13) ^ n; int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff; return 1.0 - ((float)t) * 0.931322574615478515625e-9;/// 1073741824.0); } float rs_noise_for_perlin(int x, int y) { x %= rs_perlin_conf.period; y %= rs_perlin_conf.period; // from here, http://www.cplusplus.com/forum/general/85758/ // koef. changed int n = x + y * 57 * 5; // no *2 n = (n << 13) ^ n; int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff; return 1.0 - ((float)t) * 0.931322574615478515625e-9;/// 1073741824.0); } //float rs_noise_periodical(int x, int y, int period) { // // x %= period; // y %= period; // // // from here, http://www.cplusplus.com/forum/general/85758/ // // koef. changed // int n = x + y * 57 * 5; // no *2 // n = (n << 13) ^ n; // int t = (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff; // return 1.0 - ((float)t) * 0.931322574615478515625e-9;/// 1073741824.0); //} float rs_interpolate(float x, float y, float a) { float negA = 1.0 - a; float negASqr = negA * negA; float fac1 = 3.0 * (negASqr) - 2.0 * (negASqr * negA); float aSqr = a * a; float fac2 = 3.0 * aSqr - 2.0 * (aSqr * a); return x * fac1 + y * fac2; //add the weighted factors } float rs_perlin_noise(float x, float y) { // while (x > rs_perlin_conf.tile_period) { // x -= rs_perlin_conf.tile_period; // }; // // while (y > rs_perlin_conf.tile_period) { // y -= rs_perlin_conf.tile_period; // }; int Xint = (int)x; int Yint = (int)y; float Xfrac = x - Xint; float Yfrac = y - Yint; //noise values float n01= rs_noise_for_perlin(Xint-1, Yint-1); float n02= rs_noise_for_perlin(Xint+1, Yint-1); float n03= rs_noise_for_perlin(Xint-1, Yint+1); float n04= rs_noise_for_perlin(Xint+1, Yint+1); float n05= rs_noise_for_perlin(Xint-1, Yint); float n06= rs_noise_for_perlin(Xint+1, Yint); float n07= rs_noise_for_perlin(Xint, Yint-1); float n08= rs_noise_for_perlin(Xint, Yint+1); float n09= rs_noise_for_perlin(Xint, Yint); float n12= rs_noise_for_perlin(Xint+2, Yint-1); float n14= rs_noise_for_perlin(Xint+2, Yint+1); float n16= rs_noise_for_perlin(Xint+2, Yint); float n23= rs_noise_for_perlin(Xint-1, Yint+2); float n24= rs_noise_for_perlin(Xint+1, Yint+2); float n28= rs_noise_for_perlin(Xint, Yint+2); float n34= rs_noise_for_perlin(Xint+2, Yint+2); //find the noise values of the four corners float x0y0 = 0.0625*(n01+n02+n03+n04) + 0.125*(n05+n06+n07+n08) + 0.25*(n09); float x1y0 = 0.0625*(n07+n12+n08+n14) + 0.125*(n09+n16+n02+n04) + 0.25*(n06); float x0y1 = 0.0625*(n05+n06+n23+n24) + 0.125*(n03+n04+n09+n28) + 0.25*(n08); float x1y1 = 0.0625*(n09+n16+n28+n34) + 0.125*(n08+n14+n06+n24) + 0.25*(n04); //interpolate between those values according to the x and y fractions float v1 = rs_interpolate(x0y0, x1y0, Xfrac); //interpolate in x direction (y) float v2 = rs_interpolate(x0y1, x1y1, Xfrac); //interpolate in x direction (y+1) float fin = rs_interpolate(v1, v2, Yfrac); //interpolate in y direction return fin; } float rs_perlin(float i, float j) { float t = 0.0f; float _amplitude = 1.0; int k; float amplitude_divider = 0.0; for (k = 0; k < rs_perlin_conf.octaves; k++) { amplitude_divider += _amplitude; _amplitude *= rs_perlin_conf.persistence; }; _amplitude = 1.0; float freq = rs_perlin_conf.freq; for(k = 0; k < rs_perlin_conf.octaves; k++) { t += rs_perlin_noise(j * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed, i * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed) * _amplitude; _amplitude *= rs_perlin_conf.persistence; freq *= 2; } return t / amplitude_divider; }; float rs_quad_noise(float i, float j) { float t = 0.0f; float _amplitude = 1.0; int k; float amplitude_divider = 0.0; for (k = 0; k < rs_perlin_conf.octaves; k++) { amplitude_divider += _amplitude; _amplitude *= rs_perlin_conf.persistence; }; _amplitude = 1.0; float freq = rs_perlin_conf.freq; for(k = 0; k < rs_perlin_conf.octaves; k++) { t += rs_noise(j * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed, i * freq / rs_perlin_conf.tex_size + rs_perlin_conf.seed) * _amplitude; _amplitude *= rs_perlin_conf.persistence; freq *= 2; } return t / amplitude_divider; };