kolibrios-gitea/programs/games/heliothryx/game/rsnoise.c

176 lines
5.1 KiB
C
Raw Normal View History

#include "rsnoise.h"
#include "rsgame.h"
#ifdef RS_USE_C_LIBS
#include <string.h>
#include <math.h>
#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;
};