From f9871ef16dfd77ae6ce68f1e06ca055ed02d990f Mon Sep 17 00:00:00 2001 From: tom lee Date: Tue, 4 Jan 2022 18:57:25 +0800 Subject: [PATCH] WorldGen: Now no longer gen all chunks in higher than chunk details --- .../core/builders/lodBuilding/LodBuilder.java | 11 +- .../lod/core/objects/lod/LodDimension.java | 138 +++--------------- .../lod/core/objects/lod/LodRegion.java | 20 +-- .../core/objects/opengl/LodVertexBuffer.java | 4 +- 4 files changed, 40 insertions(+), 133 deletions(-) diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java index fd29d5475..35c2da8a0 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java @@ -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); } diff --git a/src/main/java/com/seibel/lod/core/objects/lod/LodDimension.java b/src/main/java/com/seibel/lod/core/objects/lod/LodDimension.java index 10a1acffa..e77fbd412 100644 --- a/src/main/java/com/seibel/lod/core/objects/lod/LodDimension.java +++ b/src/main/java/com/seibel/lod/core/objects/lod/LodDimension.java @@ -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; } /** diff --git a/src/main/java/com/seibel/lod/core/objects/lod/LodRegion.java b/src/main/java/com/seibel/lod/core/objects/lod/LodRegion.java index dce0faee6..5c48ba045 100644 --- a/src/main/java/com/seibel/lod/core/objects/lod/LodRegion.java +++ b/src/main/java/com/seibel/lod/core/objects/lod/LodRegion.java @@ -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); } } } diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/LodVertexBuffer.java b/src/main/java/com/seibel/lod/core/objects/opengl/LodVertexBuffer.java index 77edef521..a0ed97a48 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/LodVertexBuffer.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/LodVertexBuffer.java @@ -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); } } } \ No newline at end of file