mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-09 12:16:35 -04:00
Merge branch 'Cubitect:master' into master
This commit is contained in:
commit
c9fc194cde
166
finders.c
166
finders.c
@ -4409,8 +4409,8 @@ int getParaRange(const DoublePerlinNoise *para, double *pmin, double *pmax,
|
||||
int maxrad, maxiter;
|
||||
int err = 1;
|
||||
|
||||
*pmin = DBL_MAX;
|
||||
*pmax = -DBL_MAX;
|
||||
if (pmin) *pmin = DBL_MAX;
|
||||
if (pmax) *pmax = -DBL_MAX;
|
||||
|
||||
lmin = DBL_MAX, lmax = 0;
|
||||
for (i = 0; i < para->octA.octcnt; i++)
|
||||
@ -4436,8 +4436,8 @@ int getParaRange(const DoublePerlinNoise *para, double *pmin, double *pmax,
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
if (v < *pmin) *pmin = v;
|
||||
if (v > *pmax) *pmax = v;
|
||||
if (pmin && v < *pmin) *pmin = v;
|
||||
if (pmax && v > *pmax) *pmax = v;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -4451,14 +4451,20 @@ int getParaRange(const DoublePerlinNoise *para, double *pmin, double *pmax,
|
||||
{
|
||||
for (i = 0; i < w; i += step)
|
||||
{
|
||||
v = getParaDescent(para, +factor, x, z, w, h, i, j,
|
||||
step, step, dr, data, func);
|
||||
if (v != v) goto L_end;
|
||||
if (v < *pmin) *pmin = v;
|
||||
v = -getParaDescent(para, -factor, x, z, w, h, i, j,
|
||||
step, step, dr, data, func);
|
||||
if (v != v) goto L_end;
|
||||
if (v > *pmax) *pmax = v;
|
||||
if (pmin)
|
||||
{
|
||||
v = getParaDescent(para, +factor, x, z, w, h, i, j,
|
||||
step, step, dr, data, func);
|
||||
if (v != v) goto L_end;
|
||||
if (v < *pmin) *pmin = v;
|
||||
}
|
||||
if (pmax)
|
||||
{
|
||||
v = -getParaDescent(para, -factor, x, z, w, h, i, j,
|
||||
step, step, dr, data, func);
|
||||
if (v != v) goto L_end;
|
||||
if (v > *pmax) *pmax = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4498,93 +4504,97 @@ int getParaRange(const DoublePerlinNoise *para, double *pmin, double *pmax,
|
||||
skipsiz = (ww+1) * (hh+1) * sizeof(*skip);
|
||||
skip = (char*) malloc(skipsiz);
|
||||
|
||||
// look for minima
|
||||
memset(skip, 0, skipsiz);
|
||||
if (pmin)
|
||||
{ // look for minima
|
||||
memset(skip, 0, skipsiz);
|
||||
|
||||
for (jj = 0; jj <= hh; jj++)
|
||||
{
|
||||
j = jj * step; if (j >= h) j = h-1;
|
||||
for (ii = 0; ii <= ww; ii++)
|
||||
for (jj = 0; jj <= hh; jj++)
|
||||
{
|
||||
i = ii * step; if (i >= w) i = w-1;
|
||||
if (skip[jj*ww+ii]) continue;
|
||||
|
||||
v = factor * sampleDoublePerlin(para, x+i, 0, z+j);
|
||||
if (func)
|
||||
j = jj * step; if (j >= h) j = h-1;
|
||||
for (ii = 0; ii <= ww; ii++)
|
||||
{
|
||||
int e = func(data, x+i, z+j, v);
|
||||
if (e)
|
||||
{
|
||||
err = e;
|
||||
goto L_end;
|
||||
}
|
||||
}
|
||||
// not looking for maxima yet, but we'll update the bounds anyway
|
||||
if (v > *pmax) *pmax = v;
|
||||
i = ii * step; if (i >= w) i = w-1;
|
||||
if (skip[jj*ww+ii]) continue;
|
||||
|
||||
dr = beta * (v - *pmin) / vdif;
|
||||
if (dr > 1.0)
|
||||
{ // difference is too large -> mark visinity to be skipped
|
||||
int a, b, r = (int) dr;
|
||||
for (b = 0; b < r; b++)
|
||||
v = factor * sampleDoublePerlin(para, x+i, 0, z+j);
|
||||
if (func)
|
||||
{
|
||||
if (b+jj < 0 || b+jj >= hh) continue;
|
||||
for (a = -r+1; a < r; a++)
|
||||
int e = func(data, x+i, z+j, v);
|
||||
if (e)
|
||||
{
|
||||
if (a+ii < 0 || a+ii >= ww) continue;
|
||||
skip[(b+jj)*ww + (a+ii)] = 1;
|
||||
err = e;
|
||||
goto L_end;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
// not looking for maxima yet, but update the bounds anyway
|
||||
if (pmax && v > *pmax) *pmax = v;
|
||||
|
||||
dr = beta * (v - *pmin) / vdif;
|
||||
if (dr > 1.0)
|
||||
{ // difference is too large -> mark visinity to be skipped
|
||||
int a, b, r = (int) dr;
|
||||
for (b = 0; b < r; b++)
|
||||
{
|
||||
if (b+jj < 0 || b+jj >= hh) continue;
|
||||
for (a = -r+1; a < r; a++)
|
||||
{
|
||||
if (a+ii < 0 || a+ii >= ww) continue;
|
||||
skip[(b+jj)*ww + (a+ii)] = 1;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
v = getParaDescent(para, +factor, x, z, w, h, i, j,
|
||||
maxrad, maxiter, dr, data, func);
|
||||
if (v != v) goto L_end;
|
||||
if (v < *pmin) *pmin = v;
|
||||
}
|
||||
v = getParaDescent(para, +factor, x, z, w, h, i, j,
|
||||
maxrad, maxiter, dr, data, func);
|
||||
if (v != v) goto L_end;
|
||||
if (v < *pmin) *pmin = v;
|
||||
}
|
||||
}
|
||||
|
||||
// look for maxima
|
||||
memset(skip, 0, skipsiz);
|
||||
if (pmax)
|
||||
{ // look for maxima
|
||||
memset(skip, 0, skipsiz);
|
||||
|
||||
for (jj = 0; jj <= hh; jj++)
|
||||
{
|
||||
j = jj * step; if (j >= h) j = h-1;
|
||||
for (ii = 0; ii <= ww; ii++)
|
||||
for (jj = 0; jj <= hh; jj++)
|
||||
{
|
||||
i = ii * step; if (i >= w) i = w-1;
|
||||
if (skip[jj*ww+ii]) continue;
|
||||
|
||||
v = -factor * sampleDoublePerlin(para, x+i, 0, z+j);
|
||||
if (func)
|
||||
j = jj * step; if (j >= h) j = h-1;
|
||||
for (ii = 0; ii <= ww; ii++)
|
||||
{
|
||||
int e = func(data, x+i, z+j, -v);
|
||||
if (e)
|
||||
{
|
||||
err = e;
|
||||
goto L_end;
|
||||
}
|
||||
}
|
||||
i = ii * step; if (i >= w) i = w-1;
|
||||
if (skip[jj*ww+ii]) continue;
|
||||
|
||||
dr = beta * (v + *pmax) / vdif;
|
||||
if (dr > 1.0)
|
||||
{ // difference too large -> mark visinity to be skipped
|
||||
int a, b, r = (int) dr;
|
||||
for (b = 0; b < r; b++)
|
||||
v = -factor * sampleDoublePerlin(para, x+i, 0, z+j);
|
||||
if (func)
|
||||
{
|
||||
if (b+jj < 0 || b+jj >= hh) continue;
|
||||
for (a = -r+1; a < r; a++)
|
||||
int e = func(data, x+i, z+j, -v);
|
||||
if (e)
|
||||
{
|
||||
if (a+ii < 0 || a+ii >= ww) continue;
|
||||
skip[(b+jj)*ww + (a+ii)] = 1;
|
||||
err = e;
|
||||
goto L_end;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
dr = beta * (v + *pmax) / vdif;
|
||||
if (dr > 1.0)
|
||||
{ // difference too large -> mark visinity to be skipped
|
||||
int a, b, r = (int) dr;
|
||||
for (b = 0; b < r; b++)
|
||||
{
|
||||
if (b+jj < 0 || b+jj >= hh) continue;
|
||||
for (a = -r+1; a < r; a++)
|
||||
{
|
||||
if (a+ii < 0 || a+ii >= ww) continue;
|
||||
skip[(b+jj)*ww + (a+ii)] = 1;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
v = -getParaDescent(para, -factor, x, z, w, h, i, j,
|
||||
maxrad, maxiter, dr, data, func);
|
||||
if (v != v) goto L_end;
|
||||
if (v > *pmax) *pmax = v;
|
||||
}
|
||||
v = -getParaDescent(para, -factor, x, z, w, h, i, j,
|
||||
maxrad, maxiter, dr, data, func);
|
||||
if (v != v) goto L_end;
|
||||
if (v > *pmax) *pmax = v;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -623,7 +623,7 @@ double getParaDescent(const DoublePerlinNoise *para, double factor,
|
||||
* error is returned.
|
||||
*
|
||||
* The results are written to pmin and pmax (which would be cast to an integer
|
||||
* during boime mapping).
|
||||
* during boime mapping). Nullable, to look for minima and maxima separately.
|
||||
*/
|
||||
int getParaRange(const DoublePerlinNoise *para, double *pmin, double *pmax,
|
||||
int x, int z, int w, int h, void *data, int (*func)(void*,int,int,double));
|
||||
|
2
makefile
2
makefile
@ -21,7 +21,7 @@ debug: CFLAGS += -DDEBUG -O0 -ggdb3
|
||||
debug: libcubiomes
|
||||
release: CFLAGS += -O3 -g3
|
||||
release: libcubiomes
|
||||
native: CFLAGS += -O3 -march=native
|
||||
native: CFLAGS += -O3 -march=native -ffast-math
|
||||
native: libcubiomes
|
||||
|
||||
ifeq ($(OS),Windows_NT)
|
||||
|
65
noise.c
65
noise.c
@ -5,11 +5,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
double maintainPrecision(double x)
|
||||
{
|
||||
return x - floor(x / 33554432.0 + 0.5) * 33554432.0;
|
||||
}
|
||||
|
||||
// grad()
|
||||
/*
|
||||
static double indexedLerp(int idx, double d1, double d2, double d3)
|
||||
@ -61,17 +56,18 @@ void perlinInit(PerlinNoise *noise, uint64_t *seed)
|
||||
noise->amplitude = 1.0;
|
||||
noise->lacunarity = 1.0;
|
||||
|
||||
uint8_t *idx = noise->d;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
noise->d[i] = i;
|
||||
idx[i] = i;
|
||||
}
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
int j = nextInt(seed, 256 - i) + i;
|
||||
uint8_t n = noise->d[i];
|
||||
noise->d[i] = noise->d[j];
|
||||
noise->d[j] = n;
|
||||
noise->d[i + 256] = noise->d[i];
|
||||
uint8_t n = idx[i];
|
||||
idx[i] = idx[j];
|
||||
idx[j] = n;
|
||||
idx[i + 256] = idx[i];
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,30 +81,31 @@ void xPerlinInit(PerlinNoise *noise, Xoroshiro *xr)
|
||||
noise->amplitude = 1.0;
|
||||
noise->lacunarity = 1.0;
|
||||
|
||||
uint8_t *idx = noise->d;
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
noise->d[i] = i;
|
||||
idx[i] = i;
|
||||
}
|
||||
for (i = 0; i < 256; i++)
|
||||
{
|
||||
int j = xNextInt(xr, 256 - i) + i;
|
||||
uint8_t n = noise->d[i];
|
||||
noise->d[i] = noise->d[j];
|
||||
noise->d[j] = n;
|
||||
noise->d[i + 256] = noise->d[i];
|
||||
uint8_t n = idx[i];
|
||||
idx[i] = idx[j];
|
||||
idx[j] = n;
|
||||
idx[i + 256] = idx[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
double samplePerlin(const PerlinNoise *noise, double d1, double d2, double d3,
|
||||
double yamp, double ymin)
|
||||
{
|
||||
d1 += noise->a;
|
||||
d2 += noise->b;
|
||||
d3 += noise->c;
|
||||
int i1 = (int)d1 - (int)(d1 < 0);
|
||||
int i2 = (int)d2 - (int)(d2 < 0);
|
||||
int i3 = (int)d3 - (int)(d3 < 0);
|
||||
const uint8_t *idx = noise->d;
|
||||
int i1 = (int) floor(d1);
|
||||
int i2 = (int) floor(d2);
|
||||
int i3 = (int) floor(d3);
|
||||
d1 -= i1;
|
||||
d2 -= i2;
|
||||
d3 -= i3;
|
||||
@ -126,21 +123,22 @@ double samplePerlin(const PerlinNoise *noise, double d1, double d2, double d3,
|
||||
i2 &= 0xff;
|
||||
i3 &= 0xff;
|
||||
|
||||
int a1 = noise->d[i1] + i2;
|
||||
int a2 = noise->d[a1] + i3;
|
||||
int a3 = noise->d[a1+1] + i3;
|
||||
int b1 = noise->d[i1+1] + i2;
|
||||
int b2 = noise->d[b1] + i3;
|
||||
int b3 = noise->d[b1+1] + i3;
|
||||
int a1 = idx[i1] + i2;
|
||||
int b1 = idx[i1+1] + i2;
|
||||
|
||||
double l1 = indexedLerp(noise->d[a2], d1, d2, d3);
|
||||
double l2 = indexedLerp(noise->d[b2], d1-1, d2, d3);
|
||||
double l3 = indexedLerp(noise->d[a3], d1, d2-1, d3);
|
||||
double l4 = indexedLerp(noise->d[b3], d1-1, d2-1, d3);
|
||||
double l5 = indexedLerp(noise->d[a2+1], d1, d2, d3-1);
|
||||
double l6 = indexedLerp(noise->d[b2+1], d1-1, d2, d3-1);
|
||||
double l7 = indexedLerp(noise->d[a3+1], d1, d2-1, d3-1);
|
||||
double l8 = indexedLerp(noise->d[b3+1], d1-1, d2-1, d3-1);
|
||||
int a2 = idx[a1] + i3;
|
||||
int a3 = idx[a1+1] + i3;
|
||||
int b2 = idx[b1] + i3;
|
||||
int b3 = idx[b1+1] + i3;
|
||||
|
||||
double l1 = indexedLerp(idx[a2], d1, d2, d3);
|
||||
double l2 = indexedLerp(idx[b2], d1-1, d2, d3);
|
||||
double l3 = indexedLerp(idx[a3], d1, d2-1, d3);
|
||||
double l4 = indexedLerp(idx[b3], d1-1, d2-1, d3);
|
||||
double l5 = indexedLerp(idx[a2+1], d1, d2, d3-1);
|
||||
double l6 = indexedLerp(idx[b2+1], d1-1, d2, d3-1);
|
||||
double l7 = indexedLerp(idx[a3+1], d1, d2-1, d3-1);
|
||||
double l8 = indexedLerp(idx[b3+1], d1-1, d2-1, d3-1);
|
||||
|
||||
l1 = lerp(t1, l1, l2);
|
||||
l3 = lerp(t1, l3, l4);
|
||||
@ -192,7 +190,6 @@ double sampleSimplex2D(const PerlinNoise *noise, double x, double y)
|
||||
return 70.0 * t;
|
||||
}
|
||||
|
||||
|
||||
void octaveInit(OctaveNoise *noise, uint64_t *seed, PerlinNoise *octaves,
|
||||
int omin, int len)
|
||||
{
|
||||
|
11
noise.h
11
noise.h
@ -2,6 +2,7 @@
|
||||
#define NOISE_H_
|
||||
|
||||
#include "rng.h"
|
||||
#include <math.h>
|
||||
|
||||
STRUCT(PerlinNoise)
|
||||
{
|
||||
@ -30,7 +31,15 @@ extern "C"
|
||||
#endif
|
||||
|
||||
/// Helper
|
||||
double maintainPrecision(double x);
|
||||
static inline ATTR(hot, const)
|
||||
double maintainPrecision(double x)
|
||||
{ // This is a highly performance critical function that is used to correct
|
||||
// progressing errors from float-maths. However, since cubiomes uses
|
||||
// doubles anyway, this seems useless in practice.
|
||||
|
||||
//return x - round(x / 33554432.0) * 33554432.0;
|
||||
return x;
|
||||
}
|
||||
|
||||
/// Perlin noise
|
||||
void perlinInit(PerlinNoise *noise, uint64_t *seed);
|
||||
|
Loading…
x
Reference in New Issue
Block a user