Archived
1
0
Fork 0
This repository has been archived on 2025-09-02. You can view files and clone it, but you cannot make any changes to it's state, such as pushing and creating new issues, pull requests or comments.
skcblitz/noise.h
2025-09-02 14:43:36 +02:00

225 lines
6.5 KiB
C

static const double noise_d3x[] = { 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, 0.0D, -1.0D, 0.0D };
static const double noise_d3y[] = { 1.0D, 1.0D, -1.0D, -1.0D, 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D };
static const double noise_d3z[] = { 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, 1.0D, -1.0D, -1.0D, 1.0D, 1.0D, -1.0D, -1.0D, 0.0D, 1.0D, 0.0D, -1.0D };
static const double noise_d2x[] = { 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 1.0D, -1.0D, 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, 0.0D, -1.0D, 0.0D };
static const double noise_d2z[] = { 0.0D, 0.0D, 0.0D, 0.0D, 1.0D, 1.0D, -1.0D, -1.0D, 1.0D, 1.0D, -1.0D, -1.0D, 0.0D, 1.0D, 0.0D, -1.0D };
typedef struct {
int permutations[512];
double xcoord;
double ycoord;
double zcoord;
} octave_t;
typedef struct {
octave_t *octaves;
uint n_octaves;
} noisegen_t;
void noise_oct_init(octave_t *oct, ulong *rand) {
memset(oct->permutations, 0, 512 * sizeof(int));
oct->xcoord = rng_double(rand) * 256.0D;
oct->ycoord = rng_double(rand) * 256.0D;
oct->zcoord = rng_double(rand) * 256.0D;
for(int n = 0; n < 256; oct->permutations[n] = n++) {
;
}
for(int n = 0; n < 256; ++n) {
int pos = rng_zrange(rand, 256 - n) + n;
int value = oct->permutations[n];
oct->permutations[n] = oct->permutations[pos];
oct->permutations[pos] = value;
oct->permutations[n + 256] = oct->permutations[n];
}
}
void noise_gen_init(noisegen_t *gen, ulong *rand, int octs) {
gen->n_octaves = octs;
gen->octaves = mem_alloc(octs * sizeof(octave_t), MEM_MISC);
for(int n = 0; n < octs; ++n) {
noise_oct_init(&gen->octaves[n], rand);
}
}
void noise_gen_free(noisegen_t *gen) {
if(gen->octaves)
mem_free(gen->octaves);
gen->octaves = NULL;
gen->n_octaves = 0;
}
double noise_lerp(double d, double n, double m) {
return n + d * (m - n);
}
double noise_grad2d(int n, double xm, double zm) {
int i = n & 15;
return noise_d2x[i] * xm + noise_d2z[i] * zm;
}
double noise_grad(int n, double xm, double ym, double zm) {
int i = n & 15;
return noise_d3x[i] * xm + noise_d3y[i] * ym + noise_d3z[i] * zm;
}
long noise_floor_double(double value) {
long i = (long)value;
return value < (double)i ? i - 1L : i;
}
void noise_oct_gen(octave_t *oct, double *noise, double xoff, double yoff, double zoff, int xsize, int ysize, int zsize,
double xscale, double yscale, double zscale, double scale) {
int *permutations = oct->permutations;
double xcoord = oct->xcoord;
double ycoord = oct->ycoord;
double zcoord = oct->zcoord;
if(ysize == 1) {
int i5 = 0;
int j5 = 0;
int j = 0;
int k5 = 0;
double d14 = 0.0D;
double d15 = 0.0D;
int l5 = 0;
double d16 = 1.0D / scale;
for(int j2 = 0; j2 < xsize; ++j2) {
double d17 = xoff + (double)j2 * xscale + xcoord;
int i6 = (int)d17;
if(d17 < (double)i6) {
--i6;
}
int k2 = i6 & 255;
d17 = d17 - (double)i6;
double d18 = d17 * d17 * d17 * (d17 * (d17 * 6.0D - 15.0D) + 10.0D);
for(int j6 = 0; j6 < zsize; ++j6) {
double d19 = zoff + (double)j6 * zscale + zcoord;
int k6 = (int)d19;
if(d19 < (double)k6) {
--k6;
}
int l6 = k6 & 255;
d19 = d19 - (double)k6;
double d20 = d19 * d19 * d19 * (d19 * (d19 * 6.0D - 15.0D) + 10.0D);
i5 = permutations[k2] + 0;
j5 = permutations[i5] + l6;
j = permutations[k2 + 1] + 0;
k5 = permutations[j] + l6;
d14 = noise_lerp(d18, noise_grad2d(permutations[j5], d17, d19), noise_grad(permutations[k5], d17 - 1.0D, 0.0D, d19));
d15 = noise_lerp(d18, noise_grad(permutations[j5 + 1], d17, 0.0D, d19 - 1.0D),
noise_grad(permutations[k5 + 1], d17 - 1.0D, 0.0D, d19 - 1.0D));
double d21 = noise_lerp(d20, d14, d15);
int i7 = l5++;
noise[i7] += d21 * d16;
}
}
}
else {
int i = 0;
double d0 = 1.0D / scale;
int k = -1;
int l = 0;
int i1 = 0;
int j1 = 0;
int k1 = 0;
int l1 = 0;
int i2 = 0;
double d1 = 0.0D;
double d2 = 0.0D;
double d3 = 0.0D;
double d4 = 0.0D;
for(int l2 = 0; l2 < xsize; ++l2) {
double d5 = xoff + (double)l2 * xscale + xcoord;
int i3 = (int)d5;
if(d5 < (double)i3) {
--i3;
}
int j3 = i3 & 255;
d5 = d5 - (double)i3;
double d6 = d5 * d5 * d5 * (d5 * (d5 * 6.0D - 15.0D) + 10.0D);
for(int k3 = 0; k3 < zsize; ++k3) {
double d7 = zoff + (double)k3 * zscale + zcoord;
int l3 = (int)d7;
if(d7 < (double)l3) {
--l3;
}
int i4 = l3 & 255;
d7 = d7 - (double)l3;
double d8 = d7 * d7 * d7 * (d7 * (d7 * 6.0D - 15.0D) + 10.0D);
for(int j4 = 0; j4 < ysize; ++j4) {
double d9 = yoff + (double)j4 * yscale + ycoord;
int k4 = (int)d9;
if(d9 < (double)k4) {
--k4;
}
int l4 = k4 & 255;
d9 = d9 - (double)k4;
double d10 = d9 * d9 * d9 * (d9 * (d9 * 6.0D - 15.0D) + 10.0D);
if(j4 == 0 || l4 != k) {
k = l4;
l = permutations[j3] + l4;
i1 = permutations[l] + i4;
j1 = permutations[l + 1] + i4;
k1 = permutations[j3 + 1] + l4;
l1 = permutations[k1] + i4;
i2 = permutations[k1 + 1] + i4;
d1 = noise_lerp(d6, noise_grad(permutations[i1], d5, d9, d7), noise_grad(permutations[l1], d5 - 1.0D, d9, d7));
d2 = noise_lerp(d6, noise_grad(permutations[j1], d5, d9 - 1.0D, d7),
noise_grad(permutations[i2], d5 - 1.0D, d9 - 1.0D, d7));
d3 = noise_lerp(d6, noise_grad(permutations[i1 + 1], d5, d9, d7 - 1.0D),
noise_grad(permutations[l1 + 1], d5 - 1.0D, d9, d7 - 1.0D));
d4 = noise_lerp(d6, noise_grad(permutations[j1 + 1], d5, d9 - 1.0D, d7 - 1.0D),
noise_grad(permutations[i2 + 1], d5 - 1.0D, d9 - 1.0D, d7 - 1.0D));
}
double d11 = noise_lerp(d10, d1, d2);
double d12 = noise_lerp(d10, d3, d4);
double d13 = noise_lerp(d8, d11, d12);
int j7 = i++;
noise[j7] += d13 * d0;
}
}
}
}
}
void noise_gen(noisegen_t *gen, double *noise, double xoff, double yoff, double zoff, int xsize, int ysize, int zsize,
double xscale, double yscale, double zscale) {
memset(noise, 0, sizeof(double) * xsize * ysize * zsize);
uint octaves = gen->n_octaves;
double factor = 1.0D;
for(int n = 0; n < octaves; ++n) {
double xo = xoff * factor * xscale;
double yo = yoff * factor * yscale;
double zo = zoff * factor * zscale;
long xn = noise_floor_double(xo);
long zn = noise_floor_double(zo);
xo = xo - (double)xn;
zo = zo - (double)zn;
xn = xn % 16777216L;
zn = zn % 16777216L;
xo = xo + (double)xn;
zo = zo + (double)zn;
noise_oct_gen(&gen->octaves[n], noise, xo, yo, zo, xsize, ysize, zsize, xscale * factor, yscale * factor, zscale * factor, factor);
factor /= 2.0D;
}
}