mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-23 11:45:27 -04:00
Perfromace and memory optimization for VoronoiZoom 1.15+
This commit is contained in:
parent
6f2210094f
commit
c86145a640
268
layers.c
268
layers.c
@ -356,7 +356,7 @@ static float distsq(const float *a, const float *b, int n)
|
|||||||
|
|
||||||
int getNetherBiome(const NetherNoise *nn, int x, int y, int z)
|
int getNetherBiome(const NetherNoise *nn, int x, int y, int z)
|
||||||
{
|
{
|
||||||
const float mixpoints[5][6] = {
|
const float bpoints[5][6] = {
|
||||||
{ nether_wastes, 0, 0, 0, 0, 0 },
|
{ nether_wastes, 0, 0, 0, 0, 0 },
|
||||||
{ soul_sand_valley, 0, -0.5, 0, 0, 0 },
|
{ soul_sand_valley, 0, -0.5, 0, 0, 0 },
|
||||||
{ crimson_forest, 0.4, 0, 0, 0, 0 },
|
{ crimson_forest, 0.4, 0, 0, 0, 0 },
|
||||||
@ -376,7 +376,7 @@ int getNetherBiome(const NetherNoise *nn, int x, int y, int z)
|
|||||||
float dmin = FLT_MAX;
|
float dmin = FLT_MAX;
|
||||||
for (i = 0; i < 5; i++)
|
for (i = 0; i < 5; i++)
|
||||||
{
|
{
|
||||||
float dsq = distsq(point, &mixpoints[i][1], 5);
|
float dsq = distsq(point, &bpoints[i][1], 5);
|
||||||
if (dsq < dmin)
|
if (dsq < dmin)
|
||||||
{
|
{
|
||||||
dmin = dsq;
|
dmin = dsq;
|
||||||
@ -384,7 +384,7 @@ int getNetherBiome(const NetherNoise *nn, int x, int y, int z)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
id = (int) mixpoints[id][0];
|
id = (int) bpoints[id][0];
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1999,6 +1999,23 @@ int mapOceanMix(const Layer * l, int * out, int x, int z, int w, int h)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void getVoronoiCell(int64_t sha, int a, int b, int c,
|
||||||
|
int *x, int *y, int *z)
|
||||||
|
{
|
||||||
|
int64_t s = sha;
|
||||||
|
s = mcStepSeed(s, a);
|
||||||
|
s = mcStepSeed(s, b);
|
||||||
|
s = mcStepSeed(s, c);
|
||||||
|
s = mcStepSeed(s, a);
|
||||||
|
s = mcStepSeed(s, b);
|
||||||
|
s = mcStepSeed(s, c);
|
||||||
|
|
||||||
|
*x = (((s >> 24) & 1023) - 512) * 36;
|
||||||
|
s = mcStepSeed(s, sha);
|
||||||
|
*y = (((s >> 24) & 1023) - 512) * 36;
|
||||||
|
s = mcStepSeed(s, sha);
|
||||||
|
*z = (((s >> 24) & 1023) - 512) * 36;
|
||||||
|
}
|
||||||
|
|
||||||
int mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
|
int mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
@ -2016,120 +2033,147 @@ int mapVoronoiZoom(const Layer * l, int * out, int x, int z, int w, int h)
|
|||||||
int64_t sha = l->startSalt;
|
int64_t sha = l->startSalt;
|
||||||
int *buf = (int *) malloc(w*h*sizeof(*buf));
|
int *buf = (int *) malloc(w*h*sizeof(*buf));
|
||||||
|
|
||||||
|
int x000, x001, x010, x011, x100, x101, x110, x111;
|
||||||
|
int y000, y001, y010, y011, y100, y101, y110, y111;
|
||||||
|
int z000, z001, z010, z011, z100, z101, z110, z111;
|
||||||
|
int pi, pj, ii, jj, dx, dz, pjz, pix, i4, j4;
|
||||||
|
int v00, v01, v10, v11, v;
|
||||||
|
int prev_skip;
|
||||||
|
int64_t r;
|
||||||
|
uint64_t d, dmin;
|
||||||
int i, j;
|
int i, j;
|
||||||
typedef struct Touple { int x, y, z; } Touple;
|
|
||||||
Touple *prbuf = (Touple *) malloc(2 * pW * pH * sizeof(Touple));
|
|
||||||
|
|
||||||
for (j = 0; j < pH; j++)
|
for (pj = 0; pj < pH-1; pj++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < pW; i++)
|
v00 = out[(pj+0)*pW];
|
||||||
|
v10 = out[(pj+1)*pW];
|
||||||
|
pjz = pZ + pj;
|
||||||
|
j4 = ((pjz) << 2) - z;
|
||||||
|
prev_skip = 1;
|
||||||
|
|
||||||
|
for (pi = 0; pi < pW-1; pi++)
|
||||||
{
|
{
|
||||||
int64_t s = sha;
|
PREFETCH( buf + ((pjz << 2) + 0) * w + pi, 1, 1 );
|
||||||
s = mcStepSeed(s, pX+i);
|
PREFETCH( buf + ((pjz << 2) + 1) * w + pi, 1, 1 );
|
||||||
s = mcStepSeed(s, -1);
|
PREFETCH( buf + ((pjz << 2) + 2) * w + pi, 1, 1 );
|
||||||
s = mcStepSeed(s, pZ+j);
|
PREFETCH( buf + ((pjz << 2) + 3) * w + pi, 1, 1 );
|
||||||
s = mcStepSeed(s, pX+i);
|
|
||||||
s = mcStepSeed(s, -1);
|
|
||||||
s = mcStepSeed(s, pZ+j);
|
|
||||||
|
|
||||||
int rx = (((s >> 24) & 1023) - 512) * 36;
|
v01 = out[(pj+0)*pW + (pi+1)];
|
||||||
s = mcStepSeed(s, sha);
|
v11 = out[(pj+1)*pW + (pi+1)];
|
||||||
int ry = (((s >> 24) & 1023) - 512) * 36;
|
pix = pX + pi;
|
||||||
s = mcStepSeed(s, sha);
|
i4 = ((pix) << 2) - x;
|
||||||
int rz = (((s >> 24) & 1023) - 512) * 36;
|
|
||||||
|
|
||||||
Touple *pt = prbuf + 2*(j*pW+i);
|
|
||||||
pt->x = rx;
|
|
||||||
pt->y = ry;
|
|
||||||
pt->z = rz;
|
|
||||||
|
|
||||||
s = sha;
|
|
||||||
s = mcStepSeed(s, pX+i);
|
|
||||||
s = mcStepSeed(s, 0);
|
|
||||||
s = mcStepSeed(s, pZ+j);
|
|
||||||
s = mcStepSeed(s, pX+i);
|
|
||||||
s = mcStepSeed(s, 0);
|
|
||||||
s = mcStepSeed(s, pZ+j);
|
|
||||||
|
|
||||||
rx = (((s >> 24) & 1023) - 512) * 36;
|
|
||||||
s = mcStepSeed(s, sha);
|
|
||||||
ry = (((s >> 24) & 1023) - 512) * 36;
|
|
||||||
s = mcStepSeed(s, sha);
|
|
||||||
rz = (((s >> 24) & 1023) - 512) * 36;
|
|
||||||
|
|
||||||
pt++;
|
|
||||||
pt->x = rx;
|
|
||||||
pt->y = ry;
|
|
||||||
pt->z = rz;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < h; j++)
|
|
||||||
{
|
|
||||||
for (i = 0; i < w; i++)
|
|
||||||
{
|
|
||||||
int xi = x+i;
|
|
||||||
int zj = z+j;
|
|
||||||
int pi = (xi >> 2) - pX;
|
|
||||||
int pj = (zj >> 2) - pZ;
|
|
||||||
|
|
||||||
int v00 = out[(pj+0)*pW + (pi+0)];
|
|
||||||
int v01 = out[(pj+0)*pW + (pi+1)];
|
|
||||||
int v10 = out[(pj+1)*pW + (pi+0)];
|
|
||||||
int v11 = out[(pj+1)*pW + (pi+1)];
|
|
||||||
int v = v00;
|
|
||||||
|
|
||||||
if (v00 == v01 && v00 == v10 && v00 == v11)
|
if (v00 == v01 && v00 == v10 && v00 == v11)
|
||||||
{
|
{
|
||||||
|
for (jj = 0; jj < 4; jj++)
|
||||||
|
{
|
||||||
|
j = j4 + jj;
|
||||||
|
if (j < 0 || j >= h) continue;
|
||||||
|
for (ii = 0; ii < 4; ii++)
|
||||||
|
{
|
||||||
|
i = i4 + ii;
|
||||||
|
if (i < 0 || i >= w) continue;
|
||||||
buf[j*w + i] = v00;
|
buf[j*w + i] = v00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev_skip = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (prev_skip)
|
||||||
int dx = (xi & 3) * 10240;
|
|
||||||
int dz = (zj & 3) * 10240;
|
|
||||||
|
|
||||||
uint64_t dmin = (uint64_t)-1;
|
|
||||||
int bx, bz;
|
|
||||||
for (bz = 0; bz <= 1; bz++)
|
|
||||||
{
|
{
|
||||||
for (bx = 0; bx <= 1; bx++)
|
getVoronoiCell(sha, pix, -1, pjz+0, &x000, &y000, &z000);
|
||||||
{
|
getVoronoiCell(sha, pix, 0, pjz+0, &x001, &y001, &z001);
|
||||||
int ax = pi + bx;
|
getVoronoiCell(sha, pix, -1, pjz+1, &x100, &y100, &z100);
|
||||||
int az = pj + bz;
|
getVoronoiCell(sha, pix, 0, pjz+1, &x101, &y101, &z101);
|
||||||
int64_t r;
|
prev_skip = 0;
|
||||||
uint64_t d;
|
}
|
||||||
|
getVoronoiCell(sha, pix+1, -1, pjz+0, &x010, &y010, &z010);
|
||||||
|
getVoronoiCell(sha, pix+1, 0, pjz+0, &x011, &y011, &z011);
|
||||||
|
getVoronoiCell(sha, pix+1, -1, pjz+1, &x110, &y110, &z110);
|
||||||
|
getVoronoiCell(sha, pix+1, 0, pjz+1, &x111, &y111, &z111);
|
||||||
|
|
||||||
Touple *pt = prbuf + 2*( (az)*pW + (ax) );
|
|
||||||
|
for (jj = 0; jj < 4; jj++)
|
||||||
|
{
|
||||||
|
j = j4 + jj;
|
||||||
|
if (j < 0 || j >= h) continue;
|
||||||
|
for (ii = 0; ii < 4; ii++)
|
||||||
|
{
|
||||||
|
i = i4 + ii;
|
||||||
|
if (i < 0 || i >= w) continue;
|
||||||
|
|
||||||
|
const int A = 40*1024;
|
||||||
|
const int B = 20*1024;
|
||||||
|
dx = ii * 10*1024;
|
||||||
|
dz = jj * 10*1024;
|
||||||
|
dmin = (uint64_t)-1;
|
||||||
|
|
||||||
|
v = v00;
|
||||||
d = 0;
|
d = 0;
|
||||||
r = pt->x - 40*1024*bx + dx; d += r*r;
|
r = x000 - 0 + dx; d += r*r;
|
||||||
r = pt->y + 20*1024; d += r*r;
|
r = y000 + B; d += r*r;
|
||||||
r = pt->z - 40*1024*bz + dz; d += r*r;
|
r = z000 - 0 + dz; d += r*r;
|
||||||
|
if (d < dmin) { dmin = d; }
|
||||||
if (d < dmin)
|
|
||||||
{
|
|
||||||
dmin = d;
|
|
||||||
v = out[az*pW + ax];
|
|
||||||
}
|
|
||||||
|
|
||||||
pt++;
|
|
||||||
d = 0;
|
d = 0;
|
||||||
r = pt->x - 40*1024*bx + dx; d += r*r;
|
r = x001 - 0 + dx; d += r*r;
|
||||||
r = pt->y - 20*1024; d += r*r;
|
r = y001 - B; d += r*r;
|
||||||
r = pt->z - 40*1024*bz + dz; d += r*r;
|
r = z001 - 0 + dz; d += r*r;
|
||||||
|
if (d < dmin) { dmin = d; }
|
||||||
|
|
||||||
if (d < dmin)
|
d = 0;
|
||||||
{
|
r = x010 - A + dx; d += r*r;
|
||||||
dmin = d;
|
r = y010 + B; d += r*r;
|
||||||
v = out[az*pW + ax];
|
r = z010 - 0 + dz; d += r*r;
|
||||||
}
|
if (d < dmin) { dmin = d; v = v01; }
|
||||||
}
|
d = 0;
|
||||||
}
|
r = x011 - A + dx; d += r*r;
|
||||||
|
r = y011 - B; d += r*r;
|
||||||
|
r = z011 - 0 + dz; d += r*r;
|
||||||
|
if (d < dmin) { dmin = d; v = v01; }
|
||||||
|
|
||||||
|
d = 0;
|
||||||
|
r = x100 - 0 + dx; d += r*r;
|
||||||
|
r = y100 + B; d += r*r;
|
||||||
|
r = z100 - A + dz; d += r*r;
|
||||||
|
if (d < dmin) { dmin = d; v = v10; }
|
||||||
|
d = 0;
|
||||||
|
r = x101 - 0 + dx; d += r*r;
|
||||||
|
r = y101 - B; d += r*r;
|
||||||
|
r = z101 - A + dz; d += r*r;
|
||||||
|
if (d < dmin) { dmin = d; v = v10; }
|
||||||
|
|
||||||
|
d = 0;
|
||||||
|
r = x110 - A + dx; d += r*r;
|
||||||
|
r = y110 + B; d += r*r;
|
||||||
|
r = z110 - A + dz; d += r*r;
|
||||||
|
if (d < dmin) { dmin = d; v = v11; }
|
||||||
|
d = 0;
|
||||||
|
r = x111 - A + dx; d += r*r;
|
||||||
|
r = y111 - B; d += r*r;
|
||||||
|
r = z111 - A + dz; d += r*r;
|
||||||
|
if (d < dmin) { dmin = d; v = v11; }
|
||||||
|
|
||||||
buf[j*w + i] = v;
|
buf[j*w + i] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(prbuf);
|
x000 = x010;
|
||||||
|
y000 = y010;
|
||||||
|
z000 = z010;
|
||||||
|
x100 = x110;
|
||||||
|
y100 = y110;
|
||||||
|
z100 = z110;
|
||||||
|
x001 = x011;
|
||||||
|
y001 = y011;
|
||||||
|
z001 = z011;
|
||||||
|
x101 = x111;
|
||||||
|
y101 = y111;
|
||||||
|
z101 = z111;
|
||||||
|
v00 = v01;
|
||||||
|
v10 = v11;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(out, buf, w*h*sizeof(*buf));
|
memcpy(out, buf, w*h*sizeof(*buf));
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
@ -2279,6 +2323,7 @@ void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4
|
|||||||
int dx = (x & 3) * 10240;
|
int dx = (x & 3) * 10240;
|
||||||
int dy = (y & 3) * 10240;
|
int dy = (y & 3) * 10240;
|
||||||
int dz = (z & 3) * 10240;
|
int dz = (z & 3) * 10240;
|
||||||
|
int ax = 0, ay = 0, az = 0;
|
||||||
uint64_t dmin = (uint64_t)-1;
|
uint64_t dmin = (uint64_t)-1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -2287,23 +2332,12 @@ void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4
|
|||||||
int bx = (i & 4) != 0;
|
int bx = (i & 4) != 0;
|
||||||
int by = (i & 2) != 0;
|
int by = (i & 2) != 0;
|
||||||
int bz = (i & 1) != 0;
|
int bz = (i & 1) != 0;
|
||||||
int ax = pX + bx;
|
int cx = pX + bx;
|
||||||
int ay = pY + by;
|
int cy = pY + by;
|
||||||
int az = pZ + bz;
|
int cz = pZ + bz;
|
||||||
|
int rx, ry, rz;
|
||||||
|
|
||||||
int64_t s = sha;
|
getVoronoiCell(sha, cx, cy, cz, &rx, &ry, &rz);
|
||||||
s = mcStepSeed(s, ax);
|
|
||||||
s = mcStepSeed(s, ay);
|
|
||||||
s = mcStepSeed(s, az);
|
|
||||||
s = mcStepSeed(s, ax);
|
|
||||||
s = mcStepSeed(s, ay);
|
|
||||||
s = mcStepSeed(s, az);
|
|
||||||
|
|
||||||
int rx = (((s >> 24) & 1023) - 512) * 36;
|
|
||||||
s = mcStepSeed(s, sha);
|
|
||||||
int ry = (((s >> 24) & 1023) - 512) * 36;
|
|
||||||
s = mcStepSeed(s, sha);
|
|
||||||
int rz = (((s >> 24) & 1023) - 512) * 36;
|
|
||||||
|
|
||||||
rx += dx - 40*1024*bx;
|
rx += dx - 40*1024*bx;
|
||||||
ry += dy - 40*1024*by;
|
ry += dy - 40*1024*by;
|
||||||
@ -2313,11 +2347,15 @@ void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4
|
|||||||
if (d < dmin)
|
if (d < dmin)
|
||||||
{
|
{
|
||||||
dmin = d;
|
dmin = d;
|
||||||
*x4 = ax;
|
ax = cx;
|
||||||
*y4 = ay;
|
ay = cy;
|
||||||
*z4 = az;
|
az = cz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x4) *x4 = ax;
|
||||||
|
if (y4) *y4 = ay;
|
||||||
|
if (z4) *z4 = az;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
19
layers.h
19
layers.h
@ -164,14 +164,14 @@ STRUCT(DoublePerlinNoise)
|
|||||||
|
|
||||||
STRUCT(Layer)
|
STRUCT(Layer)
|
||||||
{
|
{
|
||||||
int64_t layerSalt; // (depends only on layer salt)
|
int64_t layerSalt; // processed salt or initialization mode
|
||||||
int64_t startSalt; // (world seed dependent) = worldGenSeed, used for RND beyond the first
|
int64_t startSalt; // (depends on world seed) used to step PRNG forward
|
||||||
int64_t startSeed; // (world seed dependent) starting point for chunk seeds
|
int64_t startSeed; // (depends on world seed) starting point for chunk seeds
|
||||||
|
|
||||||
void *noise; // seed dependent data for noise maps
|
void *noise; // seed dependent data for noise maps
|
||||||
void *data; // generic data for custom layers
|
void *data; // generic data for custom layers
|
||||||
|
|
||||||
int scale; // map scale of this layer (map entry = scale x scale blocks)
|
int scale; // scale of this layer (cell = scale x scale blocks)
|
||||||
int edge; // maximum border required from parent layer
|
int edge; // maximum border required from parent layer
|
||||||
|
|
||||||
int (*getMap)(const Layer *, int *, int, int, int, int);
|
int (*getMap)(const Layer *, int *, int, int, int, int);
|
||||||
@ -232,12 +232,12 @@ int getNetherBiome(const NetherNoise *nn, int x, int y, int z);
|
|||||||
* The seed pipeline:
|
* The seed pipeline:
|
||||||
*
|
*
|
||||||
* getLayerSalt(n) -> layerSalt (ls)
|
* getLayerSalt(n) -> layerSalt (ls)
|
||||||
* layerSalt (ls) & worldSeed (ws) -> startSalt (st) & startSeed (ss)
|
* layerSalt (ls), worldSeed (ws) -> startSalt (st), startSeed (ss)
|
||||||
* startSeed (ss) & coords (x,z) -> chunkSeed (cs)
|
* startSeed (ss), coords (x,z) -> chunkSeed (cs)
|
||||||
*
|
*
|
||||||
* The chunkSeed alone is enough to generate the first RND integer with:
|
* The chunkSeed alone is enough to generate the first PRNG integer with:
|
||||||
* mcFirstInt(cs, mod)
|
* mcFirstInt(cs, mod)
|
||||||
* subsequent RND integers are generated by stepping the chunkSeed forwards,
|
* subsequent PRNG integers are generated by stepping the chunkSeed forwards,
|
||||||
* salted with startSalt:
|
* salted with startSalt:
|
||||||
* cs_next = mcStepSeed(cs, st)
|
* cs_next = mcStepSeed(cs, st)
|
||||||
*/
|
*/
|
||||||
@ -415,6 +415,9 @@ int mapOceanMix (const Layer *, int *, int, int, int, int);
|
|||||||
int mapVoronoiZoom (const Layer *, int *, int, int, int, int);
|
int mapVoronoiZoom (const Layer *, int *, int, int, int, int);
|
||||||
int mapVoronoiZoom114 (const Layer *, int *, int, int, int, int);
|
int mapVoronoiZoom114 (const Layer *, int *, int, int, int, int);
|
||||||
|
|
||||||
|
// With 1.15, biomes are only generated up to scale 1:4 OceanMix on the server-
|
||||||
|
// side while voronoi is primarily treated as a client-side access pattern.
|
||||||
|
// It is seeded by the first 8-bytes of the SHA-256 hash of the world seed.
|
||||||
int64_t getVoroniSHA(int64_t worldSeed);
|
int64_t getVoroniSHA(int64_t worldSeed);
|
||||||
void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4);
|
void voronoiAccess3D(int64_t sha, int x, int y, int z, int *x4, int *y4, int *z4);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user