mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-23 03:33:50 -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;
|
||||
}
|
||||
|
||||
|
||||
int scanForQuads(const StructureConfig sconf, int64_t s48, int64_t low20,
|
||||
int x, int z, int w, int h, Pos *qplist, int n)
|
||||
static inline
|
||||
int scanForQuadBits(const StructureConfig sconf, int radius, int64_t s48,
|
||||
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 invB = 132477LL; // = mulInv(132897987541LL, m);
|
||||
// for lbitn=20: invB = 132477LL;
|
||||
|
||||
if (n < 1)
|
||||
return 0;
|
||||
@ -687,13 +688,13 @@ int scanForQuads(const StructureConfig sconf, int64_t s48, int64_t low20,
|
||||
for (i = x; i <= x+w; 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)
|
||||
j += m;
|
||||
for (; j <= z+h; j += m)
|
||||
{
|
||||
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].z = j;
|
||||
@ -707,6 +708,26 @@ int scanForQuads(const StructureConfig sconf, int64_t s48, int64_t low20,
|
||||
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
|
||||
|
35
finders.h
35
finders.h
@ -415,20 +415,25 @@ int searchAll48(
|
||||
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
|
||||
* coordiantes. The search is performed for only a specific lower 20-bits of
|
||||
* the transformed bases (i.e. each call looks for only one constellation of
|
||||
* quad-structure).
|
||||
* coordiantes. The search is performed for only a specific set of lower bits
|
||||
* of the transformed bases (each constellation of quad-structures is
|
||||
* considered separately).
|
||||
*
|
||||
* @sconf : structure config (SWAMP_HUT_CONFIG or FEATURE_CONFIG)
|
||||
* @s48 : 48-bit seed to scan
|
||||
* @low20 : only consider transformations that yield these lower bits
|
||||
* @x,z,w,h : area to scan in region coordinates (inclusive)
|
||||
* @qplist : output region coordinates for the descovered quad-structures
|
||||
* @n : maximum number of quad-structures to look for
|
||||
* @sconf : structure config
|
||||
* @radius : radius for isQuadBase (use 128 for quad-huts)
|
||||
* @s48 : 48-bit seed to scan
|
||||
* @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)
|
||||
* @qplist : output region coordinates for the descovered quad-structures
|
||||
* @n : maximum number of quad-structures to look for
|
||||
*
|
||||
* 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);
|
||||
|
||||
//==============================================================================
|
||||
@ -442,7 +447,7 @@ int getBiomeAtPos(const LayerStack *g, const Pos pos);
|
||||
|
||||
/* Get the shadow seed.
|
||||
*/
|
||||
inline int64_t getShadow(int64_t seed)
|
||||
static inline int64_t getShadow(int64_t seed)
|
||||
{
|
||||
return -7379792620528906219LL - seed;
|
||||
}
|
||||
@ -1040,11 +1045,9 @@ static inline __attribute__((always_inline, const))
|
||||
float isQuadBaseLarge(const StructureConfig sconf, int64_t seed,
|
||||
int ax, int ay, int az, int radius)
|
||||
{
|
||||
// Good quad-monument bases are very rare indeed. There are only two seeds
|
||||
// for a radius below 148 blocks, between seed-bases 0 and 1e13:
|
||||
// 775379617447 : radius=143.30 (400,384);(384,528);(528,384);(528,528)
|
||||
// 3752024106001 : radius=145.07 (400,384);(400,560);(544,416);(528,512)
|
||||
|
||||
// Good quad-monument bases are very rare indeed and the search takes much
|
||||
// longer since it cannot be abbreviated by the low-20-bit method. For a
|
||||
// complete list of bases see the implementation of cubiomes-viewer.
|
||||
|
||||
const int64_t M = (1ULL << 48) - 1;
|
||||
const int64_t K = 0x5deece66dLL;
|
||||
|
@ -17,7 +17,7 @@ void setupLayer(Layer *l, Layer *p, int s, mapfunc_t getMap)
|
||||
l->scale = 0;
|
||||
l->edge = 0;
|
||||
l->getMap = getMap;
|
||||
l->oceanRnd = NULL;
|
||||
l->noise = NULL;
|
||||
l->data = NULL;
|
||||
}
|
||||
|
||||
@ -172,7 +172,7 @@ static void setupGeneratorImpl(LayerStack *g, int mcversion, int largeBiomes)
|
||||
{
|
||||
// ocean variants
|
||||
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_64], &l[L13_ZOOM_128], 2002, mapZoom);
|
||||
setupLayer(&l[L13_ZOOM_32], &l[L13_ZOOM_64], 2003, mapZoom);
|
||||
|
@ -85,7 +85,7 @@ STRUCT(LayerStack)
|
||||
Layer layers[L_NUM];
|
||||
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]
|
||||
OceanRnd oceanRnd;
|
||||
PerlinNoise oceanRnd;
|
||||
};
|
||||
|
||||
typedef int (*mapfunc_t)(const Layer *, int *, int, int, int, int);
|
||||
|
22
layers.c
22
layers.c
@ -4,8 +4,6 @@
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
static void oceanRndInit(OceanRnd *rnd, int64_t seed);
|
||||
|
||||
|
||||
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)
|
||||
setWorldSeed(layer->p, worldSeed);
|
||||
|
||||
if (layer->oceanRnd != NULL)
|
||||
oceanRndInit(layer->oceanRnd, worldSeed);
|
||||
if (layer->noise != NULL)
|
||||
perlinInit((PerlinNoise*)layer->noise, worldSeed);
|
||||
|
||||
int64_t ls = layer->layerSeed;
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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)
|
||||
void perlinInit(PerlinNoise *rnd, int64_t seed)
|
||||
{
|
||||
int i = 0;
|
||||
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);
|
||||
}
|
||||
@ -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 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;
|
||||
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;
|
||||
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 i, j;
|
||||
OceanRnd *rnd = l->oceanRnd;
|
||||
const PerlinNoise *rnd = (const PerlinNoise*) l->noise;
|
||||
|
||||
for (j = 0; j < h; j++)
|
||||
{
|
||||
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)
|
||||
out[i + j*w] = warm_ocean;
|
||||
|
9
layers.h
9
layers.h
@ -145,19 +145,21 @@ STRUCT(Biome)
|
||||
int mutated;
|
||||
};
|
||||
|
||||
STRUCT(OceanRnd)
|
||||
|
||||
STRUCT(PerlinNoise)
|
||||
{
|
||||
int d[512];
|
||||
double a, b, c;
|
||||
};
|
||||
|
||||
|
||||
STRUCT(Layer)
|
||||
{
|
||||
int64_t layerSeed; // (depends only on layer salt)
|
||||
int64_t startSalt; // (world seed dependent) = worldGenSeed, used for RND beyond the first
|
||||
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
|
||||
|
||||
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 perlinInit(PerlinNoise *rnd, int64_t seed);
|
||||
double samplePerlin(const PerlinNoise *rnd, double d1, double d2, double d3);
|
||||
|
||||
//==============================================================================
|
||||
// Static Helpers
|
||||
//==============================================================================
|
||||
|
Loading…
x
Reference in New Issue
Block a user