mirror of
https://github.com/Cubitect/cubiomes.git
synced 2025-09-23 03:33:50 -04:00
Added viability check for end cities + some functionality for end surface height
This commit is contained in:
parent
4ec1796806
commit
4195eab986
108
finders.c
108
finders.c
@ -1796,6 +1796,114 @@ int isViableNetherStructurePos(int structureType, int mc, NetherNoise *nn,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Given bordering noise columns and a fractional position between those,
|
||||||
|
* determine the surface block height (i.e. where the interpolated noise > 0).
|
||||||
|
* Note that the noise columns should be of size: ncolxz[ colheight+1 ]
|
||||||
|
*/
|
||||||
|
int getSurfaceHeight(
|
||||||
|
const double ncol00[], const double ncol01[],
|
||||||
|
const double ncol10[], const double ncol11[], int colheight,
|
||||||
|
int blockspercell, double dx, double dz);
|
||||||
|
|
||||||
|
void sampleNoiseColumnEnd(double column[33], const SurfaceNoise *sn,
|
||||||
|
const EndNoise *en, int x, int z);
|
||||||
|
|
||||||
|
int isViableEndCityPos(int mc, EndNoise *en, SurfaceNoise *sn,
|
||||||
|
int64_t seed, int blockX, int blockZ)
|
||||||
|
{
|
||||||
|
if (mc < MC_1_9)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
setEndSeed(en, seed);
|
||||||
|
|
||||||
|
// end biomes vary only on a per-chunk scale (1:16)
|
||||||
|
// voronoi shouldn't matter as the check will be near the chunk center
|
||||||
|
int id;
|
||||||
|
int chunkX = blockX >> 4, chunkZ = blockZ >> 4;
|
||||||
|
mapEndBiome(en, &id, chunkX, chunkZ, 1, 1);
|
||||||
|
if (!isViableFeatureBiome(mc, End_City, id))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!sn)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
initSurfaceNoiseEnd(sn, seed);
|
||||||
|
|
||||||
|
blockX = (chunkX << 4) + 7;
|
||||||
|
blockZ = (chunkZ << 4) + 7;
|
||||||
|
int cellx = (blockX >> 3);
|
||||||
|
int cellz = (blockZ >> 3);
|
||||||
|
double ncol[3][3][33];
|
||||||
|
|
||||||
|
sampleNoiseColumnEnd(ncol[0][0], sn, en, cellx, cellz);
|
||||||
|
sampleNoiseColumnEnd(ncol[0][1], sn, en, cellx, cellz+1);
|
||||||
|
sampleNoiseColumnEnd(ncol[1][0], sn, en, cellx+1, cellz);
|
||||||
|
sampleNoiseColumnEnd(ncol[1][1], sn, en, cellx+1, cellz+1);
|
||||||
|
|
||||||
|
int h00, h01, h10, h11;
|
||||||
|
h00 = getSurfaceHeight(ncol[0][0], ncol[0][1], ncol[1][0], ncol[1][1],
|
||||||
|
32, 4, (blockX & 7) / 8.0, (blockZ & 7) / 8.0);
|
||||||
|
|
||||||
|
int64_t cs;
|
||||||
|
setSeed(&cs, chunkX + chunkZ * 10387313LL);
|
||||||
|
switch (nextInt(&cs, 4))
|
||||||
|
{
|
||||||
|
case 0: // (++) 0
|
||||||
|
sampleNoiseColumnEnd(ncol[0][2], sn, en, cellx+0, cellz+2);
|
||||||
|
sampleNoiseColumnEnd(ncol[1][2], sn, en, cellx+1, cellz+2);
|
||||||
|
sampleNoiseColumnEnd(ncol[2][0], sn, en, cellx+2, cellz+0);
|
||||||
|
sampleNoiseColumnEnd(ncol[2][1], sn, en, cellx+2, cellz+1);
|
||||||
|
sampleNoiseColumnEnd(ncol[2][1], sn, en, cellx+2, cellz+2);
|
||||||
|
h01 = getSurfaceHeight(ncol[0][1], ncol[0][2], ncol[1][1], ncol[1][2],
|
||||||
|
32, 4, ((blockX ) & 7) / 8.0, ((blockZ + 5) & 7) / 8.0);
|
||||||
|
h10 = getSurfaceHeight(ncol[1][0], ncol[1][1], ncol[2][0], ncol[2][1],
|
||||||
|
32, 4, ((blockX + 5) & 7) / 8.0, ((blockZ ) & 7) / 8.0);
|
||||||
|
h11 = getSurfaceHeight(ncol[1][1], ncol[1][2], ncol[2][1], ncol[2][2],
|
||||||
|
32, 4, ((blockX + 5) & 7) / 8.0, ((blockZ + 5) & 7) / 8.0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // (-+) 90
|
||||||
|
sampleNoiseColumnEnd(ncol[0][2], sn, en, cellx+0, cellz+2);
|
||||||
|
sampleNoiseColumnEnd(ncol[1][2], sn, en, cellx+1, cellz+2);
|
||||||
|
h01 = getSurfaceHeight(ncol[0][1], ncol[0][2], ncol[1][1], ncol[1][2],
|
||||||
|
32, 4, ((blockX ) & 7) / 8.0, ((blockZ + 5) & 7) / 8.0);
|
||||||
|
h10 = getSurfaceHeight(ncol[0][0], ncol[0][1], ncol[1][0], ncol[1][1],
|
||||||
|
32, 4, ((blockX - 5) & 7) / 8.0, ((blockZ ) & 7) / 8.0);
|
||||||
|
h11 = getSurfaceHeight(ncol[0][1], ncol[0][2], ncol[1][1], ncol[1][2],
|
||||||
|
32, 4, ((blockX - 5) & 7) / 8.0, ((blockZ + 5) & 7) / 8.0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // (--) 180
|
||||||
|
h01 = getSurfaceHeight(ncol[0][0], ncol[0][1], ncol[1][0], ncol[1][1],
|
||||||
|
32, 4, ((blockX ) & 7) / 8.0, ((blockZ - 5) & 7) / 8.0);
|
||||||
|
h10 = getSurfaceHeight(ncol[0][0], ncol[0][1], ncol[1][0], ncol[1][1],
|
||||||
|
32, 4, ((blockX - 5) & 7) / 8.0, ((blockZ ) & 7) / 8.0);
|
||||||
|
h11 = getSurfaceHeight(ncol[0][0], ncol[0][1], ncol[1][0], ncol[1][1],
|
||||||
|
32, 4, ((blockX - 5) & 7) / 8.0, ((blockZ - 5) & 7) / 8.0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3: // (+-) 270
|
||||||
|
sampleNoiseColumnEnd(ncol[2][0], sn, en, cellx+2, cellz+0);
|
||||||
|
sampleNoiseColumnEnd(ncol[2][1], sn, en, cellx+2, cellz+1);
|
||||||
|
h01 = getSurfaceHeight(ncol[0][0], ncol[0][1], ncol[1][0], ncol[1][1],
|
||||||
|
32, 4, ((blockX ) & 7) / 8.0, ((blockZ - 5) & 7) / 8.0);
|
||||||
|
h10 = getSurfaceHeight(ncol[1][0], ncol[1][1], ncol[2][0], ncol[2][1],
|
||||||
|
32, 4, ((blockX + 5) & 7) / 8.0, ((blockZ ) & 7) / 8.0);
|
||||||
|
h11 = getSurfaceHeight(ncol[1][0], ncol[1][1], ncol[2][0], ncol[2][1],
|
||||||
|
32, 4, ((blockX + 5) & 7) / 8.0, ((blockZ - 5) & 7) / 8.0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0; // error
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h01 < h00) h00 = h01;
|
||||||
|
if (h10 < h00) h00 = h10;
|
||||||
|
if (h11 < h00) h00 = h11;
|
||||||
|
return h00 >= 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Finding Properties of Structures
|
// Finding Properties of Structures
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
@ -627,7 +627,8 @@ int isViableStructurePos(int structureType, int mc, LayerStack *g,
|
|||||||
int64_t seed, int blockX, int blockZ);
|
int64_t seed, int blockX, int blockZ);
|
||||||
int isViableNetherStructurePos(int structureType, int mc, NetherNoise *nn,
|
int isViableNetherStructurePos(int structureType, int mc, NetherNoise *nn,
|
||||||
int64_t seed, int blockX, int blockZ);
|
int64_t seed, int blockX, int blockZ);
|
||||||
// TODO: viability checks for end cities
|
int isViableEndCityPos(int mc, EndNoise *en, SurfaceNoise *sn,
|
||||||
|
int64_t seed, int blockX, int blockZ);
|
||||||
|
|
||||||
/* Checks if the specified structure type could generate in the given biome.
|
/* Checks if the specified structure type could generate in the given biome.
|
||||||
*/
|
*/
|
||||||
@ -726,7 +727,7 @@ int canBiomeGenerate(int layerId, int mc, int biomeID);
|
|||||||
/* Given a biome 'id' at a generation 'layer', this functions finds which
|
/* Given a biome 'id' at a generation 'layer', this functions finds which
|
||||||
* biomes may generate from it. The result is stored in the bitfields:
|
* biomes may generate from it. The result is stored in the bitfields:
|
||||||
* mL : for ids 0-63
|
* mL : for ids 0-63
|
||||||
* mM : for ids 128-192
|
* mM : for ids 128-191
|
||||||
*/
|
*/
|
||||||
void genPotential(uint64_t *mL, uint64_t *mM, int layer, int mc, int id);
|
void genPotential(uint64_t *mL, uint64_t *mM, int layer, int mc, int id);
|
||||||
|
|
||||||
|
298
layers.c
298
layers.c
@ -365,6 +365,32 @@ static double lerp(double part, double from, double to)
|
|||||||
return from + part * (to - from);
|
return from + part * (to - from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double lerp2(double dx, double dy, double v00, double v10, double v01, double v11)
|
||||||
|
{
|
||||||
|
return lerp(dy, lerp(dx, v00, v10), lerp(dx, v01, v11));
|
||||||
|
}
|
||||||
|
|
||||||
|
static double lerp3(double dx, double dy, double dz,
|
||||||
|
double v000, double v100, double v010, double v110,
|
||||||
|
double v001, double v101, double v011, double v111)
|
||||||
|
{
|
||||||
|
v000 = lerp2(dx, dy, v000, v100, v010, v110);
|
||||||
|
v001 = lerp2(dx, dy, v001, v101, v011, v111);
|
||||||
|
return lerp(dz, v000, v001);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double clampedLerp(double part, double from, double to)
|
||||||
|
{
|
||||||
|
if (part <= 0) return from;
|
||||||
|
if (part >= 1) return to;
|
||||||
|
return lerp(part, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double maintainPrecision(double x)
|
||||||
|
{
|
||||||
|
return x - floor(x / 33554432.0 + 0.5) * 33554432.0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Table of vectors to cube edge centres (12 + 4 extra) */
|
/* Table of vectors to cube edge centres (12 + 4 extra) */
|
||||||
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, 0.0, 1.0, 0.0,-1.0, 0.0};
|
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, 0.0, 1.0, 0.0,-1.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};
|
||||||
@ -377,6 +403,7 @@ static double indexedLerp(int idx, double d1, double d2, double d3)
|
|||||||
return cEdgeX[idx] * d1 + cEdgeY[idx] * d2 + cEdgeZ[idx] * d3;
|
return cEdgeX[idx] * d1 + cEdgeY[idx] * d2 + cEdgeZ[idx] * d3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void perlinInit(PerlinNoise *rnd, int64_t *seed)
|
void perlinInit(PerlinNoise *rnd, int64_t *seed)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@ -400,7 +427,8 @@ void perlinInit(PerlinNoise *rnd, int64_t *seed)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double samplePerlin(const PerlinNoise *rnd, double d1, double d2, double d3)
|
double samplePerlin(const PerlinNoise *rnd, double d1, double d2, double d3,
|
||||||
|
double yamp, double ymin)
|
||||||
{
|
{
|
||||||
d1 += rnd->a;
|
d1 += rnd->a;
|
||||||
d2 += rnd->b;
|
d2 += rnd->b;
|
||||||
@ -415,6 +443,12 @@ double samplePerlin(const PerlinNoise *rnd, double d1, double d2, double d3)
|
|||||||
double t2 = d2*d2*d2 * (d2 * (d2*6.0-15.0) + 10.0);
|
double t2 = d2*d2*d2 * (d2 * (d2*6.0-15.0) + 10.0);
|
||||||
double t3 = d3*d3*d3 * (d3 * (d3*6.0-15.0) + 10.0);
|
double t3 = d3*d3*d3 * (d3 * (d3*6.0-15.0) + 10.0);
|
||||||
|
|
||||||
|
if (yamp)
|
||||||
|
{
|
||||||
|
double yclamp = ymin < d2 ? ymin : d2;
|
||||||
|
d2 -= floor(yclamp / yamp) * yamp;
|
||||||
|
}
|
||||||
|
|
||||||
i1 &= 0xff;
|
i1 &= 0xff;
|
||||||
i2 &= 0xff;
|
i2 &= 0xff;
|
||||||
i3 &= 0xff;
|
i3 &= 0xff;
|
||||||
@ -486,77 +520,137 @@ double sampleSimplex2D(const PerlinNoise *rnd, double x, double y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void doublePerlinInit(DoublePerlinNoise *rnd, int64_t *seed,
|
void octaveInit(OctaveNoise *rnd, int64_t *seed, PerlinNoise *octaves,
|
||||||
PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len)
|
int omin, int len)
|
||||||
{
|
{
|
||||||
if (len < 1 || omin+len > 0)
|
int end = omin+len-1;
|
||||||
|
int i;
|
||||||
|
if (len < 1 || end > 0)
|
||||||
{
|
{
|
||||||
printf("doublePerlinInit(): unsupported octave range\n");
|
printf("octavePerlinInit(): unsupported octave range\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rnd->octaves[0] = octavesA;
|
rnd->octaves = octaves;
|
||||||
rnd->octaves[1] = octavesB;
|
|
||||||
rnd->octcnt = len;
|
rnd->octcnt = len;
|
||||||
|
|
||||||
rnd->amplitude = (10.0 / 6.0) * len / (len + 1);
|
if (end == 0)
|
||||||
|
|
||||||
int ab, i;
|
|
||||||
for (ab = 0; ab < 2; ab++)
|
|
||||||
{
|
{
|
||||||
// octave zero is initialized first
|
perlinInit(&rnd->octaves[0], seed);
|
||||||
if (omin <= 0 && omin+len > 0)
|
i = 1;
|
||||||
perlinInit(&rnd->octaves[ab][-omin], seed);
|
}
|
||||||
else
|
else
|
||||||
skipNextN(seed, 262);
|
|
||||||
|
|
||||||
if (omin+len < 0)
|
|
||||||
skipNextN(seed, -(omin+len) * 262);
|
|
||||||
for (i = 0; i < len; i++)
|
|
||||||
if (i+omin < 0)
|
|
||||||
perlinInit(&rnd->octaves[ab][i], seed);
|
|
||||||
|
|
||||||
rnd->persist[ab] = pow(2.0, omin+len - 1);
|
|
||||||
rnd->lacuna[ab] = 1.0 / ((1LL << len) - 1.0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static double sampleOctave(const PerlinNoise *octaves, int len,
|
|
||||||
double x, double y, double z, double persist, double lacuna)
|
|
||||||
{
|
{
|
||||||
|
skipNextN(seed, -end*262);
|
||||||
|
i = 0;
|
||||||
|
}
|
||||||
|
for (; i < len; i++)
|
||||||
|
{
|
||||||
|
perlinInit(&rnd->octaves[i], seed);
|
||||||
|
}
|
||||||
|
rnd->persist = pow(2.0, end);
|
||||||
|
rnd->lacuna = 1.0 / ((1LL << len) - 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double sampleOctave(const OctaveNoise *rnd, double x, double y, double z)
|
||||||
|
{
|
||||||
|
double persist = rnd->persist;
|
||||||
|
double lacuna = rnd->lacuna;
|
||||||
double v = 0;
|
double v = 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < rnd->octcnt; i++)
|
||||||
{
|
{
|
||||||
double ax = x * persist;
|
double ax = maintainPrecision(x * persist);
|
||||||
double ay = y * persist;
|
double ay = maintainPrecision(y * persist);
|
||||||
double az = z * persist;
|
double az = maintainPrecision(z * persist);
|
||||||
ax -= floor(ax / 33554432.0 + 0.5) * 33554432.0;
|
v += lacuna * samplePerlin(rnd->octaves+i, ax, ay, az, 0, 0);
|
||||||
ay -= floor(ay / 33554432.0 + 0.5) * 33554432.0;
|
|
||||||
az -= floor(az / 33554432.0 + 0.5) * 33554432.0;
|
|
||||||
v += lacuna * samplePerlin(octaves+i, ax, ay, az);
|
|
||||||
persist *= 0.5;
|
persist *= 0.5;
|
||||||
lacuna *= 2.0;
|
lacuna *= 2.0;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void doublePerlinInit(DoublePerlinNoise *rnd, int64_t *seed,
|
||||||
|
PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len)
|
||||||
|
{ // require: len >= 1 && omin+len <= 0
|
||||||
|
rnd->amplitude = (10.0 / 6.0) * len / (len + 1);
|
||||||
|
octaveInit(&rnd->octA, seed, octavesA, omin, len);
|
||||||
|
octaveInit(&rnd->octB, seed, octavesB, omin, len);
|
||||||
|
}
|
||||||
|
|
||||||
double sampleDoublePerlin(const DoublePerlinNoise *rnd,
|
double sampleDoublePerlin(const DoublePerlinNoise *rnd,
|
||||||
double x, double y, double z)
|
double x, double y, double z)
|
||||||
{
|
{
|
||||||
const double f = 337.0 / 331.0;
|
const double f = 337.0 / 331.0;
|
||||||
double v = 0;
|
double v = 0;
|
||||||
|
|
||||||
v += sampleOctave(rnd->octaves[0], rnd->octcnt, x, y, z,
|
v += sampleOctave(&rnd->octA, x, y, z);
|
||||||
rnd->persist[0], rnd->lacuna[0]);
|
v += sampleOctave(&rnd->octB, x*f, y*f, z*f);
|
||||||
|
|
||||||
v += sampleOctave(rnd->octaves[1], rnd->octcnt, x*f, y*f, z*f,
|
|
||||||
rnd->persist[1], rnd->lacuna[1]);
|
|
||||||
|
|
||||||
return v * rnd->amplitude;
|
return v * rnd->amplitude;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void initSurfaceNoise(SurfaceNoise *rnd, int64_t *seed,
|
||||||
|
double xzScale, double yScale, double xzFactor, double yFactor)
|
||||||
|
{
|
||||||
|
rnd->xzScale = xzScale;
|
||||||
|
rnd->yScale = yScale;
|
||||||
|
rnd->xzFactor = xzFactor;
|
||||||
|
rnd->yFactor = yFactor;
|
||||||
|
octaveInit(&rnd->octmin, seed, rnd->oct+0, -15, 16);
|
||||||
|
octaveInit(&rnd->octmax, seed, rnd->oct+16, -15, 16);
|
||||||
|
octaveInit(&rnd->octmain, seed, rnd->oct+32, -7, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void initSurfaceNoiseEnd(SurfaceNoise *rnd, int64_t seed)
|
||||||
|
{
|
||||||
|
int64_t s;
|
||||||
|
setSeed(&s, seed);
|
||||||
|
initSurfaceNoise(rnd, &s, 2.0, 1.0, 80.0, 160.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
double sampleSurfaceNoise(const SurfaceNoise *rnd, int x, int y, int z)
|
||||||
|
{
|
||||||
|
double xzScale = 684.412 * rnd->xzScale;
|
||||||
|
double yScale = 684.412 * rnd->yScale;
|
||||||
|
double xzStep = xzScale / rnd->xzFactor;
|
||||||
|
double yStep = yScale / rnd->yFactor;
|
||||||
|
|
||||||
|
double minNoise = 0;
|
||||||
|
double maxNoise = 0;
|
||||||
|
double mainNoise = 0;
|
||||||
|
double persist = 1.0;
|
||||||
|
double dx, dy, dz, sy, ty;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
dx = maintainPrecision(x * xzScale * persist);
|
||||||
|
dy = maintainPrecision(y * yScale * persist);
|
||||||
|
dz = maintainPrecision(z * xzScale * persist);
|
||||||
|
sy = yScale * persist;
|
||||||
|
ty = y * sy;
|
||||||
|
|
||||||
|
minNoise += samplePerlin(&rnd->octmin.octaves[i], dx, dy, dz, sy, ty) / persist;
|
||||||
|
maxNoise += samplePerlin(&rnd->octmax.octaves[i], dx, dy, dz, sy, ty) / persist;
|
||||||
|
|
||||||
|
if (i < 8)
|
||||||
|
{
|
||||||
|
dx = maintainPrecision(x * xzStep * persist);
|
||||||
|
dy = maintainPrecision(y * yStep * persist);
|
||||||
|
dz = maintainPrecision(z * xzStep * persist);
|
||||||
|
sy = yStep * persist;
|
||||||
|
ty = y * sy;
|
||||||
|
mainNoise += samplePerlin(&rnd->octmain.octaves[i], dx, dy, dz, sy, ty) / persist;
|
||||||
|
}
|
||||||
|
persist /= 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clampedLerp(0.5 + 0.05*mainNoise, minNoise/512.0, maxNoise/512.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Nether (1.16+) and End (1.9+) Biome Generation
|
// Nether (1.16+) and End (1.9+) Biome Generation
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -817,6 +911,122 @@ int mapEnd(const EndNoise *en, int *out, int x, int z, int w, int h)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float getEndHeightNoise(const EndNoise *en, int x, int z)
|
||||||
|
{
|
||||||
|
int hx = x / 2;
|
||||||
|
int hz = z / 2;
|
||||||
|
int oddx = x % 2;
|
||||||
|
int oddz = z % 2;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
int64_t h = 64 * (x*(int64_t)x + z*(int64_t)z);
|
||||||
|
|
||||||
|
for (j = -12; j <= 12; j++)
|
||||||
|
{
|
||||||
|
for (i = -12; i <= 12; i++)
|
||||||
|
{
|
||||||
|
int64_t rx = hx + i;
|
||||||
|
int64_t rz = hz + j;
|
||||||
|
uint16_t v = 0;
|
||||||
|
if (rx*rx + rz*rz > 4096 && sampleSimplex2D(en, rx, rz) < -0.9f)
|
||||||
|
{
|
||||||
|
v = (llabs(rx) * 3439 + llabs(rz) * 147) % 13 + 9;
|
||||||
|
rx = (oddx - i * 2);
|
||||||
|
rz = (oddz - j * 2);
|
||||||
|
int64_t noise = (rx*rx + rz*rz) * v*v;
|
||||||
|
if (noise < h)
|
||||||
|
h = noise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float ret = 100 - sqrtf((float) h);
|
||||||
|
if (ret < -100) ret = -100;
|
||||||
|
if (ret > 80) ret = 80;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sampleNoiseColumnEnd(double column[33], const SurfaceNoise *sn,
|
||||||
|
const EndNoise *en, int x, int z)
|
||||||
|
{
|
||||||
|
double depth = getEndHeightNoise(en, x, z) - 8.0f;
|
||||||
|
int y;
|
||||||
|
for (y = 0; y <= 32; y++)
|
||||||
|
{
|
||||||
|
double noise = sampleSurfaceNoise(sn, x, y, z);
|
||||||
|
noise += depth; // falloff for the End is just the depth
|
||||||
|
// clamp top and bottom slides from End settings
|
||||||
|
noise = clampedLerp((32 + 46 - y) / 64.0, -3000, noise);
|
||||||
|
noise = clampedLerp((y - 1) / 7.0, -30, noise);
|
||||||
|
column[y] = noise;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given bordering noise columns and a fractional position between those,
|
||||||
|
* determine the surface block height (i.e. where the interpolated noise > 0).
|
||||||
|
* Note that the noise columns should be of size: ncolxz[ colheight+1 ]
|
||||||
|
*/
|
||||||
|
int getSurfaceHeight(
|
||||||
|
const double ncol00[], const double ncol01[],
|
||||||
|
const double ncol10[], const double ncol11[], int colheight,
|
||||||
|
int blockspercell, double dx, double dz)
|
||||||
|
{
|
||||||
|
int y, celly;
|
||||||
|
for (celly = colheight-1; celly >= 0; celly--)
|
||||||
|
{
|
||||||
|
double v000 = ncol00[celly];
|
||||||
|
double v001 = ncol01[celly];
|
||||||
|
double v100 = ncol10[celly];
|
||||||
|
double v101 = ncol11[celly];
|
||||||
|
double v010 = ncol00[celly+1];
|
||||||
|
double v011 = ncol01[celly+1];
|
||||||
|
double v110 = ncol10[celly+1];
|
||||||
|
double v111 = ncol11[celly+1];
|
||||||
|
|
||||||
|
for (y = blockspercell - 1; y >= 0; y--)
|
||||||
|
{
|
||||||
|
double dy = y / (double) blockspercell;
|
||||||
|
double noise = lerp3(dy, dx, dz, // Note: not x, y, z
|
||||||
|
v000, v010, v100, v110,
|
||||||
|
v001, v011, v101, v111);
|
||||||
|
if (noise > 0)
|
||||||
|
return celly * blockspercell + y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSurfaceHeightEnd(int mc, int64_t seed, int x, int z)
|
||||||
|
{
|
||||||
|
(void) mc;
|
||||||
|
|
||||||
|
EndNoise en;
|
||||||
|
setEndSeed(&en, seed);
|
||||||
|
|
||||||
|
SurfaceNoise sn;
|
||||||
|
initSurfaceNoiseEnd(&sn, seed);
|
||||||
|
|
||||||
|
// end noise columns vary on a grid of cell size = eight
|
||||||
|
int cellx = (x >> 3);
|
||||||
|
int cellz = (z >> 3);
|
||||||
|
double dx = (x & 7) / 8.0;
|
||||||
|
double dz = (z & 7) / 8.0;
|
||||||
|
|
||||||
|
double ncol00[33];
|
||||||
|
double ncol01[33];
|
||||||
|
double ncol10[33];
|
||||||
|
double ncol11[33];
|
||||||
|
sampleNoiseColumnEnd(ncol00, &sn, &en, cellx, cellz);
|
||||||
|
sampleNoiseColumnEnd(ncol01, &sn, &en, cellx, cellz+1);
|
||||||
|
sampleNoiseColumnEnd(ncol10, &sn, &en, cellx+1, cellz);
|
||||||
|
sampleNoiseColumnEnd(ncol11, &sn, &en, cellx+1, cellz+1);
|
||||||
|
|
||||||
|
return getSurfaceHeight(ncol00, ncol01, ncol10, ncol11, 32, 4, dx, dz);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Layers
|
// Layers
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -2351,7 +2561,7 @@ int mapOceanTemp(const Layer * l, int * out, int x, int z, int w, int h)
|
|||||||
{
|
{
|
||||||
for (i = 0; i < w; i++)
|
for (i = 0; i < w; i++)
|
||||||
{
|
{
|
||||||
double tmp = samplePerlin(rnd, (i + x) / 8.0, (j + z) / 8.0, 0);
|
double tmp = samplePerlin(rnd, (i + x) / 8.0, (j + z) / 8.0, 0, 0, 0);
|
||||||
|
|
||||||
if (tmp > 0.4)
|
if (tmp > 0.4)
|
||||||
out[i + j*w] = warm_ocean;
|
out[i + j*w] = warm_ocean;
|
||||||
|
37
layers.h
37
layers.h
@ -142,13 +142,19 @@ STRUCT(PerlinNoise)
|
|||||||
double a, b, c;
|
double a, b, c;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STRUCT(OctaveNoise)
|
||||||
|
{
|
||||||
|
double lacuna;
|
||||||
|
double persist;
|
||||||
|
int octcnt;
|
||||||
|
PerlinNoise *octaves;
|
||||||
|
};
|
||||||
|
|
||||||
STRUCT(DoublePerlinNoise)
|
STRUCT(DoublePerlinNoise)
|
||||||
{
|
{
|
||||||
double amplitude;
|
double amplitude;
|
||||||
double lacuna[2];
|
OctaveNoise octA;
|
||||||
double persist[2];
|
OctaveNoise octB;
|
||||||
PerlinNoise *octaves[2];
|
|
||||||
int octcnt;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Layer;
|
struct Layer;
|
||||||
@ -184,6 +190,15 @@ STRUCT(NetherNoise)
|
|||||||
|
|
||||||
typedef PerlinNoise EndNoise;
|
typedef PerlinNoise EndNoise;
|
||||||
|
|
||||||
|
STRUCT(SurfaceNoise)
|
||||||
|
{
|
||||||
|
double xzScale, yScale;
|
||||||
|
double xzFactor, yFactor;
|
||||||
|
OctaveNoise octmin;
|
||||||
|
OctaveNoise octmax;
|
||||||
|
OctaveNoise octmain;
|
||||||
|
PerlinNoise oct[16+16+8];
|
||||||
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
@ -205,14 +220,25 @@ void setLayerSeed(Layer *layer, int64_t worldSeed);
|
|||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
void perlinInit(PerlinNoise *rnd, int64_t *seed);
|
void perlinInit(PerlinNoise *rnd, int64_t *seed);
|
||||||
double samplePerlin(const PerlinNoise *rnd, double x, double y, double z);
|
double samplePerlin(const PerlinNoise *rnd, double x, double y, double z,
|
||||||
|
double yamp, double ymin);
|
||||||
double sampleSimplex2D(const PerlinNoise *rnd, double x, double y);
|
double sampleSimplex2D(const PerlinNoise *rnd, double x, double y);
|
||||||
|
|
||||||
|
void octaveInit(OctaveNoise *rnd, int64_t *seed, PerlinNoise *octaves,
|
||||||
|
int omin, int len);
|
||||||
|
double sampleOctave(const OctaveNoise *rnd, double x, double y, double z);
|
||||||
|
|
||||||
void doublePerlinInit(DoublePerlinNoise *rnd, int64_t *seed,
|
void doublePerlinInit(DoublePerlinNoise *rnd, int64_t *seed,
|
||||||
PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len);
|
PerlinNoise *octavesA, PerlinNoise *octavesB, int omin, int len);
|
||||||
double sampleDoublePerlin(const DoublePerlinNoise *rnd,
|
double sampleDoublePerlin(const DoublePerlinNoise *rnd,
|
||||||
double x, double y, double z);
|
double x, double y, double z);
|
||||||
|
|
||||||
|
void initSurfaceNoise(SurfaceNoise *rnd, int64_t *seed,
|
||||||
|
double xzScale, double yScale, double xzFactor, double yFactor);
|
||||||
|
void initSurfaceNoiseEnd(SurfaceNoise *rnd, int64_t seed);
|
||||||
|
double sampleSurfaceNoise(const SurfaceNoise *rnd, int x, int y, int z);
|
||||||
|
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Nether (1.16+) and End (1.9+) Biome Generation
|
// Nether (1.16+) and End (1.9+) Biome Generation
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
@ -251,6 +277,7 @@ int mapNether3D(const NetherNoise *nn, int *out, int x, int z, int w, int h, int
|
|||||||
void setEndSeed(EndNoise *en, int64_t seed);
|
void setEndSeed(EndNoise *en, int64_t seed);
|
||||||
int mapEndBiome(const EndNoise *en, int *out, int x, int z, int w, int h);
|
int mapEndBiome(const EndNoise *en, int *out, int x, int z, int w, int h);
|
||||||
int mapEnd(const EndNoise *en, int *out, int x, int z, int w, int h);
|
int mapEnd(const EndNoise *en, int *out, int x, int z, int w, int h);
|
||||||
|
int getSurfaceHeightEnd(int mc, int64_t seed, int x, int z);
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
// Seed Helpers
|
// Seed Helpers
|
||||||
|
Loading…
x
Reference in New Issue
Block a user