WorldGen: Now no longer gen all chunks in higher than chunk details

This commit is contained in:
tom lee
2022-01-04 18:57:25 +08:00
parent 054988851d
commit f9871ef16d
4 changed files with 40 additions and 133 deletions
@@ -176,6 +176,7 @@ public class LodBuilder
return;
// determine how many LODs to generate horizontally
byte minDetailLevel = region.getMinDetailLevel();
HorizontalResolution detail = DetailDistanceUtil.getLodGenDetail(minDetailLevel);
@@ -201,12 +202,14 @@ public class LodBuilder
//lodDim.clear(detailLevel, posX, posZ);
if (data != null && data.length != 0)
{
posX = LevelPosUtil.convert((byte) 0, chunk.getChunkPosX() * 16 + startX, detail.detailLevel);
posZ = LevelPosUtil.convert((byte) 0, chunk.getChunkPosZ() * 16 + startZ, detail.detailLevel);
lodDim.addVerticalData(detailLevel, posX, posZ, data, false);
posX = LevelPosUtil.convert((byte) 0, chunk.getChunkPosX() * 16 + startX, minDetailLevel);
posZ = LevelPosUtil.convert((byte) 0, chunk.getChunkPosZ() * 16 + startZ, minDetailLevel);
if (!lodDim.doesDataExist(minDetailLevel, posX, posZ)) {
lodDim.addVerticalData(minDetailLevel, posX, posZ, data, false);
lodDim.updateData(minDetailLevel, posX, posZ);
}
}
}
lodDim.updateData(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getChunkPosX(), chunk.getChunkPosZ());
//executeTime = System.currentTimeMillis() - executeTime;
//if (executeTime > 0) ClientApi.LOGGER.info("generateLodNodeFromChunk level: " + detailLevel + " time ms: " + executeTime);
}
@@ -565,128 +565,36 @@ public class LodDimension
dx = 0;
dz = -1;
// We can use two type of generation scheduling
switch (CONFIG.client().worldGenerator().getGenerationPriority())
{
case NEAR_FIRST:
//in the NEAR_FIRST generation scheduling we prioritize the nearest un-generated position to the player
//the chunk position to generate will be stored in a posToGenerate object
posToGenerate = new PosToGenerateContainer((byte) 10, maxDataToGenerate, playerBlockPosX, playerBlockPosZ);
int playerChunkX = LevelPosUtil.getChunkPos(LodUtil.BLOCK_DETAIL_LEVEL, playerBlockPosX);
int playerChunkZ = LevelPosUtil.getChunkPos(LodUtil.BLOCK_DETAIL_LEVEL, playerBlockPosZ);
int complexity;
int xChunkToCheck;
int zChunkToCheck;
byte detailLevel;
int posX;
int posZ;
long data;
int numbChunksWide = (width) * 32;
int circleLimit = Integer.MAX_VALUE;
//posToGenerate is using an insertion sort algorithm which can become really fast if the
//original data order is almost ordered. For this reason we explore the matrix of the position to generate
//with a spiral matrix visit (a square spiral is almost ordered in the "nearest to farthest" order)
for (int i = 0; i < numbChunksWide * numbChunksWide; i++)
{
//Firstly we check if the posToGenerate has been filled
if (maxDataToGenerate == 0)
{
maxDataToGenerate--;
//if it has been filled then we set a stop distance
//the stop distance will be current distance (generically x) per square root of 2
//this would guarantee a circular generation since (Math.abs(x) * 1.41f) is the
//radius of a circle that inscribe a square
circleLimit = (int) (Math.abs(x) * 1.41f);
}
//This second if check if we reached the circleLimit decided in the previous if
//if so we stop
else if (maxDataToGenerate < 0)
{
if (circleLimit < Math.abs(x) && circleLimit < Math.abs(z))
break;
}
xChunkToCheck = x + playerChunkX;
zChunkToCheck = z + playerChunkZ;
//we get the lod region in which the chunk is present
lodRegion = getRegion(LodUtil.CHUNK_DETAIL_LEVEL, xChunkToCheck, zChunkToCheck);
if (lodRegion == null)
continue;
//Now we check if the current chunk has been generated with the correct complexity
//if(lodRegion.isChunkPreGenerated(xChunkToCheck,zChunkToCheck))
// complexity = DistanceGenerationMode.SERVER.complexity;
//else
complexity = CONFIG.client().worldGenerator().getDistanceGenerationMode().complexity;
//we create the level position info of the chunk
detailLevel = lodRegion.getMinDetailLevel();
posX = LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, xChunkToCheck, detailLevel);
posZ = LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, zChunkToCheck, detailLevel);
data = getSingleData(detailLevel, posX, posZ);
//we will generate the position only if the current generation complexity is lower than the target one.
//an un-generated area will always have 0 generation
if (DataPointUtil.getGenerationMode(data) < complexity)
{
posToGenerate.addPosToGenerate(detailLevel, posX, posZ);
if (maxDataToGenerate >= 0)
maxDataToGenerate--;
}
//with this code section we find the next chunk to check
if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z)))
{
t = dx;
dx = -dz;
dz = t;
}
x += dx;
z += dz;
}
break;
//in the FAR_FIRST generation we dedicate part of the generation process to the far region with really
//low detail quality.
default:
case FAR_FIRST:
//in the FAR_FIRST generation we dedicate part of the generation process to the far region with really
//low detail quality.
posToGenerate = new PosToGenerateContainer((byte) 8, maxDataToGenerate, playerBlockPosX, playerBlockPosZ);
int xRegion;
int zRegion;
for (int i = 0; i < width * width; i++)
{
xRegion = x + center.x;
zRegion = z + center.z;
posToGenerate = new PosToGenerateContainer((byte) 8, maxDataToGenerate, playerBlockPosX, playerBlockPosZ);
//All of this is handled directly by the region, which scan every pos from top to bottom of the quad tree
lodRegion = getRegion(xRegion, zRegion);
if (lodRegion != null)
lodRegion.getPosToGenerate(posToGenerate, playerBlockPosX, playerBlockPosZ);
int xRegion;
int zRegion;
for (int i = 0; i < width * width; i++)
//with this code section we find the next chunk to check
if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z)))
{
xRegion = x + center.x;
zRegion = z + center.z;
//All of this is handled directly by the region, which scan every pos from top to bottom of the quad tree
lodRegion = getRegion(xRegion, zRegion);
if (lodRegion != null)
lodRegion.getPosToGenerate(posToGenerate, playerBlockPosX, playerBlockPosZ);
//with this code section we find the next chunk to check
if ((x == z) || ((x < 0) && (x == -z)) || ((x > 0) && (x == 1 - z)))
{
t = dx;
dx = -dz;
dz = t;
}
x += dx;
z += dz;
t = dx;
dx = -dz;
dz = t;
}
break;
x += dx;
z += dz;
}
return posToGenerate;
return posToGenerate;
}
/**
@@ -162,7 +162,7 @@ public class LodRegion
// The dataContainer could have null entries if the
// detailLevel changes.
if (this.dataContainer[detailLevel] == null)
this.dataContainer[detailLevel] = new VerticalLevelContainer(detailLevel);
return false;//this.dataContainer[detailLevel] = new VerticalLevelContainer(detailLevel);
this.dataContainer[detailLevel].addData(data, posX, posZ, verticalIndex);
@@ -183,7 +183,7 @@ public class LodRegion
// The dataContainer could have null entries if the
// detailLevel changes.
if (this.dataContainer[detailLevel] == null)
this.dataContainer[detailLevel] = new VerticalLevelContainer(detailLevel);
return false;//this.dataContainer[detailLevel] = new VerticalLevelContainer(detailLevel);
return this.dataContainer[detailLevel].addVerticalData(data, posX, posZ);
}
@@ -248,7 +248,7 @@ public class LodRegion
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel);
// calculate what LevelPos are in range to generate
int maxDistance = LevelPosUtil.maxDistance(detailLevel, childOffsetPosX, childOffsetPosZ, playerPosX, playerPosZ, regionPosX, regionPosZ);
int minDistance = LevelPosUtil.minDistance(detailLevel, childOffsetPosX, childOffsetPosZ, playerPosX, playerPosZ, regionPosX, regionPosZ);
// determine this child's levelPos
byte childDetailLevel = (byte) (detailLevel - 1);
@@ -257,7 +257,7 @@ public class LodRegion
int childSize = 1 << (LodUtil.REGION_DETAIL_LEVEL - childDetailLevel);
byte targetDetailLevel = DetailDistanceUtil.getLodGenDetail(DetailDistanceUtil.getGenerationDetailFromDistance(maxDistance)).detailLevel;
byte targetDetailLevel = DetailDistanceUtil.getGenerationDetailFromDistance(minDistance);
if (targetDetailLevel <= detailLevel)
{
if (targetDetailLevel == detailLevel)
@@ -299,14 +299,10 @@ public class LodRegion
{
// The detail Level is smaller than a chunk.
// Only recurse down the top right child.
if (DetailDistanceUtil.getLodGenDetail(childDetailLevel).detailLevel <= (childDetailLevel))
{
if (!doesDataExist(childDetailLevel, childPosX, childPosZ))
posToGenerate.addPosToGenerate(childDetailLevel, childPosX + regionPosX * childSize, childPosZ + regionPosZ * childSize);
else
getPosToGenerate(posToGenerate, childDetailLevel, childPosX, childPosZ, playerPosX, playerPosZ);
}
if (!doesDataExist(childDetailLevel, childPosX, childPosZ))
posToGenerate.addPosToGenerate(childDetailLevel, childPosX + regionPosX * childSize, childPosZ + regionPosZ * childSize);
else
getPosToGenerate(posToGenerate, childDetailLevel, childPosX, childPosZ, playerPosX, playerPosZ);
}
}
}
@@ -47,7 +47,7 @@ public class LodVertexBuffer implements AutoCloseable
this.id = GL32.glGenBuffers();
this.isBufferStorage = isBufferStorage;
count++;
ClientApi.LOGGER.info("LodVertexBuffer Count: "+count);
//ClientApi.LOGGER.info("LodVertexBuffer Count: "+count);
}
@@ -59,7 +59,7 @@ public class LodVertexBuffer implements AutoCloseable
GLProxy.getInstance().recordOpenGlCall(() -> GL32.glDeleteBuffers(this.id));
this.id = -1;
count--;
ClientApi.LOGGER.info("LodVertexBuffer Count: "+count);
//ClientApi.LOGGER.info("LodVertexBuffer Count: "+count);
}
}
}