mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-24 04:03:39 -04:00
Ocean RNG to perlin noise + scanForQuads scan whole set.
1) specify that ocean RNG is perlin noise (nether biomes will use double-perlin & simplex) 2) scanForQuads now scans a whole set of lower bits
This commit is contained in:
parent
c8af11082a
commit
dd7e61999b
35
finders.c
35
finders.c
@ -672,13 +672,14 @@ L_ERR:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
int scanForQuads(const StructureConfig sconf, int64_t s48, int64_t low20,
|
int scanForQuadBits(const StructureConfig sconf, int radius, int64_t s48,
|
||||||
int x, int z, int w, int h, Pos *qplist, int n)
|
int64_t lbit, int lbitn, int64_t invB, int x, int z, int w, int h,
|
||||||
|
Pos *qplist, int n)
|
||||||
{
|
{
|
||||||
const int m = (1LL << 20);
|
const int m = (1LL << lbitn);
|
||||||
const int64_t A = 341873128712LL;
|
const int64_t A = 341873128712LL;
|
||||||
const int64_t invB = 132477LL; // = mulInv(132897987541LL, m);
|
// for lbitn=20: invB = 132477LL;
|
||||||
|
|
||||||
if (n < 1)
|
if (n < 1)
|
||||||
return 0;
|
return 0;
|
||||||
@ -687,13 +688,13 @@ int scanForQuads(const StructureConfig sconf, int64_t s48, int64_t low20,
|
|||||||
for (i = x; i <= x+w; i++)
|
for (i = x; i <= x+w; i++)
|
||||||
{
|
{
|
||||||
int64_t sx = s48 + A * i;
|
int64_t sx = s48 + A * i;
|
||||||
j = (z & ~(m-1)) | ((low20 - sx) * invB & (m-1));
|
j = (z & ~(m-1)) | ((lbit - sx) * invB & (m-1));
|
||||||
if (j < z)
|
if (j < z)
|
||||||
j += m;
|
j += m;
|
||||||
for (; j <= z+h; j += m)
|
for (; j <= z+h; j += m)
|
||||||
{
|
{
|
||||||
int64_t sp = moveStructure(s48, -i, -j);
|
int64_t sp = moveStructure(s48, -i, -j);
|
||||||
if (isQuadBase(sconf, sp - sconf.salt, 128))
|
if (isQuadBase(sconf, sp - sconf.salt, radius))
|
||||||
{
|
{
|
||||||
qplist[cnt].x = i;
|
qplist[cnt].x = i;
|
||||||
qplist[cnt].z = j;
|
qplist[cnt].z = j;
|
||||||
@ -707,6 +708,26 @@ int scanForQuads(const StructureConfig sconf, int64_t s48, int64_t low20,
|
|||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int scanForQuads(
|
||||||
|
const StructureConfig sconf, int radius, int64_t s48,
|
||||||
|
const int64_t *lowBits, int lowBitCnt, int lowBitN,
|
||||||
|
int x, int z, int w, int h, Pos *qplist, int n)
|
||||||
|
{
|
||||||
|
int i, cnt = 0;
|
||||||
|
const int64_t invB = mulInv(132897987541LL, (1LL << lowBitN));
|
||||||
|
|
||||||
|
for (i = 0; i < lowBitCnt; i++)
|
||||||
|
{
|
||||||
|
cnt += scanForQuadBits(sconf, radius, s48, lowBits[i], lowBitN, invB,
|
||||||
|
x, z, w, h, qplist+cnt, n-cnt);
|
||||||
|
if (cnt >= n)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Checking Biomes & Biome Helper Functions
|
// Checking Biomes & Biome Helper Functions
|
||||||
|
27
finders.h
27
finders.h
@ -415,20 +415,25 @@ int searchAll48(
|
|||||||
Pos getOptimalAfk(Pos p[4], int ax, int ay, int az, int *spcnt);
|
Pos getOptimalAfk(Pos p[4], int ax, int ay, int az, int *spcnt);
|
||||||
|
|
||||||
/* Scans the seed 's48' for quad-structures in the given area of region
|
/* Scans the seed 's48' for quad-structures in the given area of region
|
||||||
* coordiantes. The search is performed for only a specific lower 20-bits of
|
* coordiantes. The search is performed for only a specific set of lower bits
|
||||||
* the transformed bases (i.e. each call looks for only one constellation of
|
* of the transformed bases (each constellation of quad-structures is
|
||||||
* quad-structure).
|
* considered separately).
|
||||||
*
|
*
|
||||||
* @sconf : structure config (SWAMP_HUT_CONFIG or FEATURE_CONFIG)
|
* @sconf : structure config
|
||||||
|
* @radius : radius for isQuadBase (use 128 for quad-huts)
|
||||||
* @s48 : 48-bit seed to scan
|
* @s48 : 48-bit seed to scan
|
||||||
* @low20 : only consider transformations that yield these lower bits
|
* @lowBits : consider transformations that yield one of these lower bits
|
||||||
|
* @lowBitCnt : length of lower bit subset
|
||||||
|
* @lowBitN : number of bits in the subset values (0 < lowBitN <= 48)
|
||||||
* @x,z,w,h : area to scan in region coordinates (inclusive)
|
* @x,z,w,h : area to scan in region coordinates (inclusive)
|
||||||
* @qplist : output region coordinates for the descovered quad-structures
|
* @qplist : output region coordinates for the descovered quad-structures
|
||||||
* @n : maximum number of quad-structures to look for
|
* @n : maximum number of quad-structures to look for
|
||||||
*
|
*
|
||||||
* Returns the number of quad-structures found (up to 'n').
|
* Returns the number of quad-structures found (up to 'n').
|
||||||
*/
|
*/
|
||||||
int scanForQuads(const StructureConfig sconf, int64_t s48, int64_t low20,
|
int scanForQuads(
|
||||||
|
const StructureConfig sconf, int radius, int64_t s48,
|
||||||
|
const int64_t *lowBits, int lowBitCnt, int lowBitN,
|
||||||
int x, int z, int w, int h, Pos *qplist, int n);
|
int x, int z, int w, int h, Pos *qplist, int n);
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -442,7 +447,7 @@ int getBiomeAtPos(const LayerStack *g, const Pos pos);
|
|||||||
|
|
||||||
/* Get the shadow seed.
|
/* Get the shadow seed.
|
||||||
*/
|
*/
|
||||||
inline int64_t getShadow(int64_t seed)
|
static inline int64_t getShadow(int64_t seed)
|
||||||
{
|
{
|
||||||
return -7379792620528906219LL - seed;
|
return -7379792620528906219LL - seed;
|
||||||
}
|
}
|
||||||
@ -1040,11 +1045,9 @@ static inline __attribute__((always_inline, const))
|
|||||||
float isQuadBaseLarge(const StructureConfig sconf, int64_t seed,
|
float isQuadBaseLarge(const StructureConfig sconf, int64_t seed,
|
||||||
int ax, int ay, int az, int radius)
|
int ax, int ay, int az, int radius)
|
||||||
{
|
{
|
||||||
// Good quad-monument bases are very rare indeed. There are only two seeds
|
// Good quad-monument bases are very rare indeed and the search takes much
|
||||||
// for a radius below 148 blocks, between seed-bases 0 and 1e13:
|
// longer since it cannot be abbreviated by the low-20-bit method. For a
|
||||||
// 775379617447 : radius=143.30 (400,384);(384,528);(528,384);(528,528)
|
// complete list of bases see the implementation of cubiomes-viewer.
|
||||||
// 3752024106001 : radius=145.07 (400,384);(400,560);(544,416);(528,512)
|
|
||||||
|
|
||||||
|
|
||||||
const int64_t M = (1ULL << 48) - 1;
|
const int64_t M = (1ULL << 48) - 1;
|
||||||
const int64_t K = 0x5deece66dLL;
|
const int64_t K = 0x5deece66dLL;
|
||||||
|
@ -17,7 +17,7 @@ void setupLayer(Layer *l, Layer *p, int s, mapfunc_t getMap)
|
|||||||
l->scale = 0;
|
l->scale = 0;
|
||||||
l->edge = 0;
|
l->edge = 0;
|
||||||
l->getMap = getMap;
|
l->getMap = getMap;
|
||||||
l->oceanRnd = NULL;
|
l->noise = NULL;
|
||||||
l->data = NULL;
|
l->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ static void setupGeneratorImpl(LayerStack *g, int mcversion, int largeBiomes)
|
|||||||
{
|
{
|
||||||
// ocean variants
|
// ocean variants
|
||||||
setupLayer(&l[L13_OCEAN_TEMP_256], NULL, 2, mapOceanTemp);
|
setupLayer(&l[L13_OCEAN_TEMP_256], NULL, 2, mapOceanTemp);
|
||||||
l[L13_OCEAN_TEMP_256].oceanRnd = &g->oceanRnd;
|
l[L13_OCEAN_TEMP_256].noise = &g->oceanRnd;
|
||||||
setupLayer(&l[L13_ZOOM_128], &l[L13_OCEAN_TEMP_256], 2001, mapZoom);
|
setupLayer(&l[L13_ZOOM_128], &l[L13_OCEAN_TEMP_256], 2001, mapZoom);
|
||||||
setupLayer(&l[L13_ZOOM_64], &l[L13_ZOOM_128], 2002, mapZoom);
|
setupLayer(&l[L13_ZOOM_64], &l[L13_ZOOM_128], 2002, mapZoom);
|
||||||
setupLayer(&l[L13_ZOOM_32], &l[L13_ZOOM_64], 2003, mapZoom);
|
setupLayer(&l[L13_ZOOM_32], &l[L13_ZOOM_64], 2003, mapZoom);
|
||||||
|
@ -85,7 +85,7 @@ STRUCT(LayerStack)
|
|||||||
Layer layers[L_NUM];
|
Layer layers[L_NUM];
|
||||||
Layer *entry_1; // entry layer, scale (1:1) [L_VORONOI_ZOOM_1]
|
Layer *entry_1; // entry layer, scale (1:1) [L_VORONOI_ZOOM_1]
|
||||||
Layer *entry_4; // entry layer, scale (1:4) [L_RIVER_MIX_4|L13_OCEAN_MIX_4]
|
Layer *entry_4; // entry layer, scale (1:4) [L_RIVER_MIX_4|L13_OCEAN_MIX_4]
|
||||||
OceanRnd oceanRnd;
|
PerlinNoise oceanRnd;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*mapfunc_t)(const Layer *, int *, int, int, int, int);
|
typedef int (*mapfunc_t)(const Layer *, int *, int, int, int, int);
|
||||||
|
22
layers.c
22
layers.c
@ -4,8 +4,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
static void oceanRndInit(OceanRnd *rnd, int64_t seed);
|
|
||||||
|
|
||||||
|
|
||||||
void initAddBiome(int id, int tempCat, int biometype, float temp, float height)
|
void initAddBiome(int id, int tempCat, int biometype, float temp, float height)
|
||||||
{
|
{
|
||||||
@ -137,8 +135,8 @@ void setWorldSeed(Layer *layer, int64_t worldSeed)
|
|||||||
if (layer->p != NULL)
|
if (layer->p != NULL)
|
||||||
setWorldSeed(layer->p, worldSeed);
|
setWorldSeed(layer->p, worldSeed);
|
||||||
|
|
||||||
if (layer->oceanRnd != NULL)
|
if (layer->noise != NULL)
|
||||||
oceanRndInit(layer->oceanRnd, worldSeed);
|
perlinInit((PerlinNoise*)layer->noise, worldSeed);
|
||||||
|
|
||||||
int64_t ls = layer->layerSeed;
|
int64_t ls = layer->layerSeed;
|
||||||
if (ls != 0) // Pre 1.13 the Hills branch stays zero-initialized
|
if (ls != 0) // Pre 1.13 the Hills branch stays zero-initialized
|
||||||
@ -1616,11 +1614,7 @@ int mapRiverMix(const Layer * l, int * out, int x, int z, int w, int h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void perlinInit(PerlinNoise *rnd, int64_t seed)
|
||||||
/* Initialises data for the ocean temperature types using the world seed.
|
|
||||||
* This function is called when the world seed is applied in setWorldSeed().
|
|
||||||
*/
|
|
||||||
static void oceanRndInit(OceanRnd *rnd, int64_t seed)
|
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
memset(rnd, 0, sizeof(*rnd));
|
memset(rnd, 0, sizeof(*rnd));
|
||||||
@ -1643,7 +1637,7 @@ static void oceanRndInit(OceanRnd *rnd, int64_t seed)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static double lerp(const double part, const double from, const double to)
|
static double lerp(double part, double from, double to)
|
||||||
{
|
{
|
||||||
return from + part * (to - from);
|
return from + part * (to - from);
|
||||||
}
|
}
|
||||||
@ -1653,14 +1647,14 @@ const double cEdgeX[] = {1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 0.0, 0.0, 0.0,
|
|||||||
const double cEdgeY[] = {1.0, 1.0,-1.0,-1.0, 0.0, 0.0, 0.0, 0.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0};
|
const double cEdgeY[] = {1.0, 1.0,-1.0,-1.0, 0.0, 0.0, 0.0, 0.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0, 1.0,-1.0};
|
||||||
const double cEdgeZ[] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 0.0, 1.0, 0.0,-1.0};
|
const double cEdgeZ[] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0,-1.0,-1.0, 1.0, 1.0,-1.0,-1.0, 0.0, 1.0, 0.0,-1.0};
|
||||||
|
|
||||||
static double indexedLerp(int idx, const double d1, const double d2, const double d3)
|
static double indexedLerp(int idx, double d1, double d2, double d3)
|
||||||
{
|
{
|
||||||
idx &= 0xf;
|
idx &= 0xf;
|
||||||
return cEdgeX[idx] * d1 + cEdgeY[idx] * d2 + cEdgeZ[idx] * d3;
|
return cEdgeX[idx] * d1 + cEdgeY[idx] * d2 + cEdgeZ[idx] * d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static double getOceanTemp(const OceanRnd *rnd, double d1, double d2, double d3)
|
double samplePerlin(const PerlinNoise *rnd, double d1, double d2, double d3)
|
||||||
{
|
{
|
||||||
d1 += rnd->a;
|
d1 += rnd->a;
|
||||||
d2 += rnd->b;
|
d2 += rnd->b;
|
||||||
@ -1709,13 +1703,13 @@ static double getOceanTemp(const OceanRnd *rnd, double d1, double d2, double d3)
|
|||||||
int mapOceanTemp(const Layer * l, int * out, int x, int z, int w, int h)
|
int mapOceanTemp(const Layer * l, int * out, int x, int z, int w, int h)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i, j;
|
||||||
OceanRnd *rnd = l->oceanRnd;
|
const PerlinNoise *rnd = (const PerlinNoise*) l->noise;
|
||||||
|
|
||||||
for (j = 0; j < h; j++)
|
for (j = 0; j < h; j++)
|
||||||
{
|
{
|
||||||
for (i = 0; i < w; i++)
|
for (i = 0; i < w; i++)
|
||||||
{
|
{
|
||||||
double tmp = getOceanTemp(rnd, (i + x) / 8.0, (j + z) / 8.0, 0);
|
double tmp = samplePerlin(rnd, (i + x) / 8.0, (j + z) / 8.0, 0);
|
||||||
|
|
||||||
if (tmp > 0.4)
|
if (tmp > 0.4)
|
||||||
out[i + j*w] = warm_ocean;
|
out[i + j*w] = warm_ocean;
|
||||||
|
9
layers.h
9
layers.h
@ -145,19 +145,21 @@ STRUCT(Biome)
|
|||||||
int mutated;
|
int mutated;
|
||||||
};
|
};
|
||||||
|
|
||||||
STRUCT(OceanRnd)
|
|
||||||
|
STRUCT(PerlinNoise)
|
||||||
{
|
{
|
||||||
int d[512];
|
int d[512];
|
||||||
double a, b, c;
|
double a, b, c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
STRUCT(Layer)
|
STRUCT(Layer)
|
||||||
{
|
{
|
||||||
int64_t layerSeed; // (depends only on layer salt)
|
int64_t layerSeed; // (depends only on layer salt)
|
||||||
int64_t startSalt; // (world seed dependent) = worldGenSeed, used for RND beyond the first
|
int64_t startSalt; // (world seed dependent) = worldGenSeed, used for RND beyond the first
|
||||||
int64_t startSeed; // (world seed dependent) starting point for chunk seeds
|
int64_t startSeed; // (world seed dependent) starting point for chunk seeds
|
||||||
|
|
||||||
OceanRnd *oceanRnd; // world seed dependent data for ocean temperatures
|
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; // map scale of this layer (map entry = scale x scale blocks)
|
||||||
@ -187,6 +189,9 @@ void initBiomes();
|
|||||||
void setWorldSeed(Layer *layer, int64_t worldSeed);
|
void setWorldSeed(Layer *layer, int64_t worldSeed);
|
||||||
|
|
||||||
|
|
||||||
|
void perlinInit(PerlinNoise *rnd, int64_t seed);
|
||||||
|
double samplePerlin(const PerlinNoise *rnd, double d1, double d2, double d3);
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Static Helpers
|
// Static Helpers
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
Loading…
x
Reference in New Issue
Block a user