test: trying to understand where the chain breaks

i am doing some tests to understand where the chain breaks inside Layer.cpp and i think it is something related to zoom.
This commit is contained in:
Lord_Cambion 2026-05-18 14:48:43 +02:00
parent 500f35e306
commit 8723ba023b
11 changed files with 272 additions and 246 deletions

View file

@ -917,58 +917,54 @@ void ServerLevel::initializeLevel(LevelSettings *settings)
*/
void ServerLevel::setInitialSpawn(LevelSettings *levelSettings)
{
if (!dimension->mayRespawn())
{
levelData->setSpawn(0, dimension->getSpawnYPosition(), 0);
return;
}
if (!dimension->mayRespawn())
{
levelData->setSpawn(0, dimension->getSpawnYPosition(), 0);
return;
}
isFindingSpawn = true;
isFindingSpawn = true;
BiomeSource *biomeSource = dimension->biomeSource;
vector<Biome *> playerSpawnBiomes = biomeSource->getPlayerSpawnBiomes();
Random random(getSeed());
BiomeSource *biomeSource = dimension->biomeSource;
vector<Biome *> playerSpawnBiomes = biomeSource->getPlayerSpawnBiomes();
Random random(getSeed());
TilePos *findBiome = biomeSource->findBiome(0, 0, 16 * 16, playerSpawnBiomes, &random);
TilePos *spawnPos = biomeSource->findBiome(0, 0, 256, playerSpawnBiomes, &random);
int xSpawn = 0; // (Level.MAX_LEVEL_SIZE - 100) * 0;
int ySpawn = dimension->getSpawnYPosition();
int zSpawn = 0; // (Level.MAX_LEVEL_SIZE - 100) * 0;
int minXZ = - (dimension->getXZSize() * 16 ) / 2;
int maxXZ = (dimension->getXZSize() * 16 ) / 2 - 1;
int xSpawn = 0;
int ySpawn = dimension->getSpawnYPosition();
int zSpawn = 0;
int minXZ = -(dimension->getXZSize() * 16) / 2;
int maxXZ = (dimension->getXZSize() * 16) / 2 - 1;
if (findBiome != nullptr)
{
xSpawn = findBiome->x;
zSpawn = findBiome->z;
delete findBiome;
}
else
{
app.DebugPrintf("Level::setInitialSpawn - Unable to find spawn biome\n");
}
if (spawnPos != nullptr)
{
xSpawn = spawnPos->x;
zSpawn = spawnPos->z;
delete spawnPos;
}
else
{
app.DebugPrintf("Level::setInitialSpawn - Unable to find spawn biome\n");
}
int tries = 0;
int tries = 0;
while (!dimension->isValidSpawn(xSpawn, zSpawn))
{
xSpawn += random.nextInt(64) - random.nextInt(64);
if (xSpawn > maxXZ) xSpawn = 0;
if (xSpawn < minXZ) xSpawn = 0;
zSpawn += random.nextInt(64) - random.nextInt(64);
if (zSpawn > maxXZ) zSpawn = 0;
if (zSpawn < minXZ) zSpawn = 0;
if (++tries == 1000) break;
}
while (!dimension->isValidSpawn(xSpawn, zSpawn))
{
// 4J-PB changed to stay within our level limits
xSpawn += random.nextInt(64) - random.nextInt(64);
if(xSpawn>maxXZ) xSpawn=0;
if(xSpawn<minXZ) xSpawn=0;
zSpawn += random.nextInt(64) - random.nextInt(64);
if(zSpawn>maxXZ) zSpawn=0;
if(zSpawn<minXZ) zSpawn=0;
levelData->setSpawn(xSpawn, ySpawn, zSpawn);
if (levelSettings->hasStartingBonusItems())
generateBonusItemsNearSpawn();
if (++tries == 1000) break;
}
levelData->setSpawn(xSpawn, ySpawn, zSpawn);
if (levelSettings->hasStartingBonusItems())
{
generateBonusItemsNearSpawn();
}
isFindingSpawn = false;
isFindingSpawn = false;
}
// 4J - brought forward from 1.3.2

View file

@ -23,13 +23,10 @@ intArray AddEdgeLayer::coolWarm(int xo, int yo, int w, int h)
intArray b = parent->getArea(xo - 1, yo - 1, w + 2, h + 2);
intArray result = IntCache::allocate(w * h);
int stride = w + 2;
for (int iy = 0; iy < h; ++iy)
{
for (int ix = 0; ix < w; ++ix)
{
initRandom(ix + xo, iy + yo);
int center = b[(ix + 1) + (iy + 1) * stride];
if (center == 1)
{
@ -37,10 +34,8 @@ intArray AddEdgeLayer::coolWarm(int xo, int yo, int w, int h)
int east = b[(ix + 2) + (iy + 1) * stride];
int west = b[(ix + 0) + (iy + 1) * stride];
int south = b[(ix + 1) + (iy + 2) * stride];
bool hasCold = (north == 3 || east == 3 || west == 3 || south == 3);
bool hasIcy = (north == 4 || east == 4 || west == 4 || south == 4);
if (hasCold || hasIcy)
center = 2;
}
@ -56,11 +51,11 @@ intArray AddEdgeLayer::heatIce(int xo, int yo, int w, int h)
intArray b = parent->getArea(xo - 1, yo - 1, w + 2, h + 2);
intArray result = IntCache::allocate(w * h);
int stride = w + 2;
for (int iy = 0; iy < h; ++iy)
{
for (int ix = 0; ix < w; ++ix)
{
initRandom(ix + xo, iy + yo);
int center = b[(ix + 1) + (iy + 1) * stride];
if (center == 4)
{
@ -68,11 +63,9 @@ intArray AddEdgeLayer::heatIce(int xo, int yo, int w, int h)
int east = b[(ix + 2) + (iy + 1) * stride];
int west = b[(ix + 0) + (iy + 1) * stride];
int south = b[(ix + 1) + (iy + 2) * stride];
bool nearWarm = (north == 2 || east == 2 || west == 2 || south == 2);
bool nearHot = (north == 1 || east == 1 || west == 1 || south == 1);
if (nearHot || nearWarm || nearWarm)
if (nearHot || nearWarm)
center = 3;
}
result[ix + iy * w] = center;

View file

@ -109,7 +109,7 @@ void Biome::staticCtor()
Biome::smallerExtremeHills = (new ExtremeHillsBiome(20))->setColor(0x72789a)->setName(L"Extreme Hills Edge")->setDepthAndScale(0.2f, 0.8f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHillsEdge, eMinecraftColour_Foliage_ExtremeHillsEdge, eMinecraftColour_Water_ExtremeHillsEdge,eMinecraftColour_Sky_ExtremeHillsEdge);
Biome::jungle = (new JungleBiome(21, false))->setColor(0x537b09)->setName(L"Jungle")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(0.2f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle);
Biome::jungleHills = (new JungleBiome(22, false))->setColor(0x2c4205)->setName(L"Jungle Hills")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(1.8f, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_JungleHills, eMinecraftColour_Foliage_JungleHills, eMinecraftColour_Water_JungleHills,eMinecraftColour_Sky_JungleHills);
Biome::jungleEdge = (new JungleBiome(23, true))->setColor(0x6458135)->setName(L"Jungle Edge")->setLeafColor(0x5470985)->setTemperatureAndDownfall(0.95F, 0.8F);
Biome::jungleEdge = (new JungleBiome(23, true))->setColor(0x6458135)->setName(L"Jungle Edge")->setLeafColor(0x5470985)->setTemperatureAndDownfall(0.95F, 0.8F)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle);
Biome::deepOcean= (new OceanBiome(24))->setName(L"Deep Ocean")->setDepthAndScale(-1.8,0.1f)->setColor(0x000070)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean);;
Biome::stoneBeach = (new StoneBeachBiome(25))->setColor(0xa2a284)->setName(L"Stone Beach")->setTemperatureAndDownfall(0.2f, 0.3f)->setDepthAndScale(-1.0f, 0.1f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills,eMinecraftColour_Foliage_ExtremeHills,eMinecraftColour_Water_ExtremeHills,eMinecraftColour_Sky_ExtremeHills);
Biome::coldBeach = (new BeachBiome(26))->setColor(0xFAF0C0)->setName(L"Cold Beach")->setTemperatureAndDownfall(0.05F, 0.3F)->setDepthAndScale(0.0F, 0.025F)->setSnowCovered()->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IcePlains, eMinecraftColour_Foliage_IcePlains, eMinecraftColour_Water_IcePlains, eMinecraftColour_Sky_IcePlains);

View file

@ -15,11 +15,11 @@ void BiomeSource::_init()
generatorOptions = L"";
cache = new BiomeCache(this);
playerSpawnBiomes.push_back(Biome::plains);
playerSpawnBiomes.push_back(Biome::forest);
playerSpawnBiomes.push_back(Biome::plains);
playerSpawnBiomes.push_back(Biome::taiga);
playerSpawnBiomes.push_back(Biome::forestHills);
playerSpawnBiomes.push_back(Biome::taigaHills);
playerSpawnBiomes.push_back(Biome::forestHills);
playerSpawnBiomes.push_back(Biome::jungle);
playerSpawnBiomes.push_back(Biome::jungleHills);
}

View file

@ -16,29 +16,25 @@ intArray GrowMushroomIslandLayer::getArea(int xo, int yo, int w, int h)
int ph = h + 2;
intArray p = parent->getArea(px, py, pw, ph);
intArray result = IntCache::allocate(w * h);
int mushroomId = Biome::mushroomIsland->id;
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
int ul = p[(x + 0) + (y + 0) * pw];
int ur = p[(x + 2) + (y + 0) * pw];
int dl = p[(x + 0) + (y + 2) * pw];
int dr = p[(x + 2) + (y + 2) * pw];
int c = p[(x + 1) + (y + 1) * pw];
int north = p[(x + 1) + (y + 0) * pw];
int south = p[(x + 1) + (y + 2) * pw];
int west = p[(x + 0) + (y + 1) * pw];
int east = p[(x + 2) + (y + 1) * pw];
if (ul == mushroomId || ur == mushroomId ||
dl == mushroomId || dr == mushroomId ||
north == mushroomId || south == mushroomId ||
west == mushroomId || east == mushroomId)
int south = p[(x + 1) + (y + 2) * pw];
if (ul == 14 || ur == 14 || dl == 14 || dr == 14)
{
result[x + y * w] = mushroomId;
result[x + y * w] = 14;
}
else if (north == 14 || east == 14 || south == 14)
{
result[x + y * w] = 14;
}
else
{

View file

@ -18,7 +18,6 @@ libdivide::divider<long long> fast_d6(6);
libdivide::divider<long long> fast_d7(7);
libdivide::divider<long long> fast_d10(10);
#endif
LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* superflatConfig)
{
int32_t seed32 = (int32_t)seed;
@ -65,9 +64,37 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* sup
riverLayerFinal = make_shared<SmoothLayer>(seed32, riverLayerFinal, 0x3E8);
shared_ptr<Layer> biomeLayer = make_shared<BiomeInitLayer>(seed32, baseLayer, 0xC8, levelType, superflatConfig);
{
auto testBiome = make_shared<BiomeInitLayer>(seed32, baseLayer, 0xC8, levelType, superflatConfig);
testBiome->init((uint32_t)seed);
IntCache::releaseAll();
intArray testArea = testBiome->getArea(0, 0, 20, 20);
app.DebugPrintf("BiomeInitLayer only seed=%d:\n", seed32);
for (int z = 0; z < 20; z++) {
for (int x = 0; x < 20; x++)
app.DebugPrintf("%3d ", testArea[x + z*20]);
app.DebugPrintf("\n");
}
IntCache::releaseAll();
}
biomeLayer = make_shared<BiomeEdgeLayer>(seed32, biomeLayer, 0x3E8);
biomeLayer = make_shared<RegionHillsLayer>(seed32, biomeLayer, hillsNoise, 0x3E8);
{
auto testLayer = biomeLayer;
testLayer->init((uint32_t)seed);
IntCache::releaseAll();
intArray testArea = testLayer->getArea(0, 0, 20, 20);
app.DebugPrintf("After RegionHillsLayer seed=%d:\n", seed32);
for (int z = 0; z < 20; z++) {
for (int x = 0; x < 20; x++)
app.DebugPrintf("%3d ", testArea[x + z*20]);
app.DebugPrintf("\n");
}
IntCache::releaseAll();
}
biomeLayer = make_shared<RareBiomeSpotLayer>(seed32, biomeLayer, 0x3E9);
for (int i = 0; i < zoomLevel; ++i)
@ -86,19 +113,44 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* sup
}
biomeLayer = make_shared<SmoothLayer>(seed32, biomeLayer, 0x3E8);
{
auto testLayer = biomeLayer;
testLayer->init((uint32_t)seed);
IntCache::releaseAll();
intArray testArea = testLayer->getArea(60, 240, 20, 20);
app.DebugPrintf("After zoom loop seed=%d:\n", seed32);
for (int z = 0; z < 20; z++) {
for (int x = 0; x < 20; x++)
app.DebugPrintf("%3d ", testArea[x + z*20]);
app.DebugPrintf("\n");
}
IntCache::releaseAll();
}
shared_ptr<Layer> mixed = make_shared<RiverMixerLayer>(seed32, biomeLayer, riverLayerFinal, 0x64);
shared_ptr<Layer> voronoi = make_shared<VoronoiZoom>(seed32, mixed, 0xA);
mixed->init((uint32_t)seed);
voronoi->init((uint32_t)seed);
IntCache::releaseAll();
mixed->init((uint32_t)seed);
intArray testArea = mixed->getArea(0, 200, 60, 60);
app.DebugPrintf("Biomes 0-60, 200-260 seed=%d:\n", seed32);
for (int z = 0; z < 60; z++) {
for (int x = 0; x < 60; x++)
app.DebugPrintf("%3d ", testArea[x + z*60]);
app.DebugPrintf("\n");
}
IntCache::releaseAll();
LayerArray result(3, false);
result[0] = mixed;
result[1] = voronoi;
result[2] = mixed;
return result;
}
Layer::Layer(int64_t s)
{
int64_t sm = (int64_t)(int32_t)s;
@ -132,41 +184,40 @@ void Layer::initRandom(int64_t x, int64_t y)
int Layer::nextRandom(int max)
{
int32_t hi = (int32_t)(rval >> 32);
int result = (hi >> 24) % max;
int64_t rval_full = this->rval;
uint32_t rval_lo = (uint32_t)rval_full;
uint32_t rval_hi = (uint32_t)(rval_full >> 32);
uint32_t seed_lo = (uint32_t)this->seed;
int result = (int)((int64_t)(rval_full >> 24) % (int64_t)max);
if (result < 0) result += max;
int64_t v = rval;
int64_t lo = (int64_t)(int32_t)(
(int32_t)v * (1284865837 * (int32_t)v - 144211633)
+ (int32_t)seed);
int64_t hi64 = v * (0x5851F42D4C957F2DLL * v + 0x14057B7EF767814FLL) + seed;
rval = (hi64 & 0xFFFFFFFF00000000LL) | (uint32_t)lo;
uint32_t new_lo = rval_lo * (1284865837u * rval_lo - 144211633u) + seed_lo;
uint64_t paired = ((uint64_t)rval_lo << 32) | (uint64_t)rval_lo;
uint64_t big = (uint64_t)(int64_t)rval_full * (0x5851F42D4C957F2DULL * paired + 0x14057B7EF767814FULL);
uint32_t carry = (uint32_t)(((uint64_t)(rval_lo * (1284865837u * rval_lo - 144211633u)) + seed_lo) >> 32);
uint32_t new_hi = seed_lo + carry + (uint32_t)(big >> 32);
this->rval = ((int64_t)new_hi << 32) | (int64_t)new_lo;
return result;
}
void Layer::init(int64_t seed)
void Layer::init(int64_t worldSeed)
{
if (parent != nullptr)
parent->init(seed);
uint32_t lo = (uint32_t)seed;
uint32_t m = (uint32_t)seedMixup;
uint32_t v12 = lo * (1284865837u * lo - 144211633u);
uint32_t sum = v12 + m;
uint32_t step1 = sum * (1284865837u * sum - 144211633u);
uint32_t sum2 = step1 + m;
int64_t step2 = (int64_t)(int32_t)sum2
* (0x5851F42D4C957F2DLL * (int64_t)(int32_t)sum2
+ 0x14057B7EF767814FLL)
+ (int64_t)(int32_t)m;
static bool first = true;
parent->init(worldSeed);
this->seed = step2;
uint32_t ws = (uint32_t)worldSeed;
int64_t m = this->seedMixup;
uint32_t v12 = ws * (1284865837u * ws - 144211633u);
int64_t sum1 = (int64_t)(int32_t)v12 + m;
uint32_t v14_lo = (uint32_t)sum1 * (1284865837u * (uint32_t)sum1 - 144211633u);
int64_t sum2 = (int64_t)(int32_t)v14_lo + m;
this->seed = sum2 * (0x5851F42D4C957F2DLL * sum2 + 0x14057B7EF767814FLL) + m;
}
bool Layer::isOcean(int biomeId)

View file

@ -120,7 +120,7 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h)
}
else if (k == Biome::ocean->id)
{
// java: ocean → deepOcean
i1 = Biome::deepOcean->id;
}
else if (k == Biome::extremeHills->id)
@ -129,14 +129,19 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h)
}
else if (k == Biome::savanna->id)
{
// Java: savanna → savannaPlateau
i1 = Biome::savannaPlateau->id;
}
else if (k == Biome::deepOcean->id && nextRandom(3) == 0)
else if (k == Biome::deepOcean->id)
{
i1 = (nextRandom(2) == 0) ? Biome::plains->id : Biome::forest->id;
if (nextRandom(3) == 0)
{
if (nextRandom(2) == 0)
i1 = Biome::plains->id;
else
i1 = Biome::forest->id;
}
}

View file

@ -9,17 +9,15 @@ RiverInitLayer::RiverInitLayer(int64_t seed, std::shared_ptr<Layer> parent, int6
intArray RiverInitLayer::getArea(int xo, int yo, int w, int h)
{
intArray b = parent->getArea(xo, yo, w, h);
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
initRandom(x + xo, y + yo);
result[x + y * w] = b[x + y * w] > 0 ? nextRandom(2) + 2 : 0;
}
}
return result;
intArray b = parent->getArea(xo, yo, w, h);
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
initRandom(x + xo, y + yo);
result[x + y * w] = b[x + y * w] > 0 ? nextRandom(299999) + 2 : 0;
}
}
return result;
}

View file

@ -9,32 +9,33 @@ RiverLayer::RiverLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup
intArray RiverLayer::getArea(int xo, int yo, int w, int h)
{
int px = xo - 1;
int py = yo - 1;
int pw = w + 2;
int ph = h + 2;
intArray p = parent->getArea(px, py, pw, ph);
int px = xo - 1;
int py = yo - 1;
int pw = w + 2;
int ph = h + 2;
intArray p = parent->getArea(px, py, pw, ph);
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
int c = p[(x + 1) + (y + 1) * pw];
int n = p[(x + 1) + (y + 0) * pw];
int e = p[(x + 2) + (y + 1) * pw];
int s = p[(x + 1) + (y + 2) * pw];
int w1 = p[(x + 0) + (y + 1) * pw];
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
int l = p[(x + 0) + (y + 1) * pw];
int r = p[(x + 2) + (y + 1) * pw];
int u = p[(x + 1) + (y + 0) * pw];
int d = p[(x + 1) + (y + 2) * pw];
int c = p[(x + 1) + (y + 1) * pw];
if (c == 0 || (l == 0 || r == 0 || u == 0 || d == 0) || c != l || c != u || c != r || c != d)
{
result[x + y * w] = Biome::river->id;
}
else
{
result[x + y * w] = -1;
}
}
}
int cc = c >= 2 ? (c & 1) + 2 : c;
int nc = n >= 2 ? (n & 1) + 2 : n;
int ec = e >= 2 ? (e & 1) + 2 : e;
int sc = s >= 2 ? (s & 1) + 2 : s;
int wc = w1 >= 2 ? (w1 & 1) + 2 : w1;
return result;
if (cc == nc && cc == ec && cc == sc && cc == wc)
result[x + y * w] = -1;
else
result[x + y * w] = Biome::river->id;
}
}
return result;
}

View file

@ -8,38 +8,40 @@ SmoothLayer::SmoothLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMix
intArray SmoothLayer::getArea(int xo, int yo, int w, int h)
{
int px = xo - 1;
int py = yo - 1;
int pw = w + 2;
int ph = h + 2;
intArray p = parent->getArea(px, py, pw, ph);
int px = xo - 1;
int py = yo - 1;
int pw = w + 2;
int ph = h + 2;
intArray p = parent->getArea(px, py, pw, ph);
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
int l = p[(x + 0) + (y + 1) * pw];
int r = p[(x + 2) + (y + 1) * pw];
int u = p[(x + 1) + (y + 0) * pw];
int d = p[(x + 1) + (y + 2) * pw];
int c = p[(x + 1) + (y + 1) * pw];
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
int l = p[(x + 0) + (y + 1) * pw];
int r = p[(x + 2) + (y + 1) * pw];
int u = p[(x + 1) + (y + 0) * pw];
int d = p[(x + 1) + (y + 2) * pw];
int c = p[(x + 1) + (y + 1) * pw];
if (l == r && u == d)
{
initRandom((x + xo), (y + yo));
if (nextRandom(2) == 0) c = l;
else c = u;
if (l == r && u == d)
{
initRandom(x + xo, y + yo);
if (nextRandom(2) == 0) c = l;
else c = u;
}
else if (l == r)
{
initRandom(x + xo, y + yo);
if (nextRandom(2) == 0) c = l;
}
else if (u == d)
{
c = u;
}
}
else
{
if (l == r) c = l;
if (u == d) c = u;
}
result[x + y * w] = c;
}
}
return result;
result[x + y * w] = c;
}
}
return result;
}

View file

@ -2,88 +2,72 @@
#include "net.minecraft.world.level.newbiome.layer.h"
#include "System.h"
VoronoiZoom::VoronoiZoom(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
VoronoiZoom::VoronoiZoom(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seed)
{
this->parent = parent;
this->parent = parent;
}
intArray VoronoiZoom::getArea(int xo, int yo, int w, int h)
{
xo -= 2;
yo -= 2;
int bits = 2;
int ss = 1 << bits;
int px = xo >> bits;
int py = yo >> bits;
int pw = (w >> bits) + 3;
int ph = (h >> bits) + 3;
intArray p = parent->getArea(px, py, pw, ph);
xo -= 2;
yo -= 2;
int px = xo >> 2;
int py = yo >> 2;
int pw = (w >> 2) + 2;
int ph = (h >> 2) + 2;
intArray p = parent->getArea(px, py, pw, ph);
int ww = pw << 2;
intArray tmp = IntCache::allocate(ww * (ph << 2));
int ww = pw << bits;
int hh = ph << bits;
intArray tmp = IntCache::allocate(ww * hh);
for (int y = 0; y < ph - 1; y++)
{
int ul = p[(0 + 0) + (y + 0) * pw];
int dl = p[(0 + 0) + (y + 1) * pw];
for (int x = 0; x < pw - 1; x++)
{
double s = ss * 0.9;
initRandom((x + px) << bits, (y + py) << bits);
double x0 = (nextRandom(1024) / 1024.0 - 0.5) * s;
double y0 = (nextRandom(1024) / 1024.0 - 0.5) * s;
initRandom((x + px + 1) << bits, (y + py) << bits);
double x1 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss;
double y1 = (nextRandom(1024) / 1024.0 - 0.5) * s;
initRandom((x + px) << bits, (y + py + 1) << bits);
double x2 = (nextRandom(1024) / 1024.0 - 0.5) * s;
double y2 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss;
initRandom((x + px + 1) << bits, (y + py + 1) << bits);
double x3 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss;
double y3 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss;
for (int y = 0; y < ph - 1; y++)
{
int ul = p[0 + y * pw];
int dl = p[0 + (y + 1) * pw];
for (int x = 0; x < pw - 1; x++)
{
initRandom((x + px) << 2, (y + py) << 2);
double x0 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6;
double y0 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6;
initRandom((x + px + 1) << 2, (y + py) << 2);
double x1 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6 + 4.0;
double y1 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6;
initRandom((x + px) << 2, (y + py + 1) << 2);
double x2 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6;
double y2 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6 + 4.0;
initRandom((x + px + 1) << 2, (y + py + 1) << 2);
double x3 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6 + 4.0;
double y3 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6 + 4.0;
int ur = p[(x + 1) + y * pw];
int dr = p[(x + 1) + (y + 1) * pw];
int ur = p[(x + 1) + (y + 0) * pw];
int dr = p[(x + 1) + (y + 1) * pw];
for (int yy = 0; yy < 4; yy++)
{
int pp = ((y << 2) + yy) * ww + (x << 2);
for (int xx = 0; xx < 4; xx++)
{
double d0 = (xx - x0) * (xx - x0) + (yy - y0) * (yy - y0);
double d1 = (xx - x1) * (xx - x1) + (yy - y1) * (yy - y1);
double d2 = (xx - x2) * (xx - x2) + (yy - y2) * (yy - y2);
double d3 = (xx - x3) * (xx - x3) + (yy - y3) * (yy - y3);
if (d0 < d1 && d0 < d2 && d0 < d3)
tmp[pp++] = ul;
else if (d1 < d0 && d1 < d2 && d1 < d3)
tmp[pp++] = ur;
else if (d2 < d0 && d2 < d1 && d2 < d3)
tmp[pp++] = dl;
else
tmp[pp++] = dr;
}
}
ul = ur;
dl = dr;
}
}
for (int yy = 0; yy < ss; yy++)
{
int pp = ((y << bits) + yy) * ww + ((x << bits));
for (int xx = 0; xx < ss; xx++)
{
double d0 = ((yy - y0) * (yy - y0) + (xx - x0) * (xx - x0));
double d1 = ((yy - y1) * (yy - y1) + (xx - x1) * (xx - x1));
double d2 = ((yy - y2) * (yy - y2) + (xx - x2) * (xx - x2));
double d3 = ((yy - y3) * (yy - y3) + (xx - x3) * (xx - x3));
if (d0 < d1 && d0 < d2 && d0 < d3)
{
tmp[pp++] = ul;
}
else if (d1 < d0 && d1 < d2 && d1 < d3)
{
tmp[pp++] = ur;
}
else if (d2 < d0 && d2 < d1 && d2 < d3)
{
tmp[pp++] = dl;
}
else
{
tmp[pp++] = dr;
}
}
}
ul = ur;
dl = dr;
}
}
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
{
System::arraycopy(tmp, (y + (yo & (ss - 1))) * (pw << bits) + (xo & (ss - 1)), &result, y * w, w);
}
return result;
intArray result = IntCache::allocate(w * h);
for (int y = 0; y < h; y++)
System::arraycopy(tmp, (y + (yo & 3)) * ww + (xo & 3), &result, y * w, w);
return result;
}
int VoronoiZoom::random(int a, int b)