Optimized the regen

This commit is contained in:
Leonardo
2021-08-29 16:42:44 +02:00
parent 450f15ad36
commit b19a80f411
4 changed files with 127 additions and 122 deletions
@@ -129,11 +129,10 @@ public class LodBufferBuilder
// only allow one generation process to happen at a time
if (generatingBuffers)
return;
if (buildableBuffers == null)
// setupBuffers hasn't been called yet
return;
generatingBuffers = true;
@@ -166,7 +165,7 @@ public class LodBufferBuilder
// =====================//
RegionPos playerRegionPos = new RegionPos(playerChunkPos);
if(center == null)
if (center == null)
center = playerRegionPos;
if (setsToRender == null)
@@ -190,101 +189,99 @@ public class LodBufferBuilder
xRegion + lodDim.getCenterX() - Math.floorDiv(lodDim.getWidth(), 2),
zRegion + lodDim.getCenterZ() - Math.floorDiv(lodDim.getWidth(), 2));
if(lodDim.regen[xRegion][zRegion])
// local position in the vbo and bufferBuilder arrays
BufferBuilder currentBuffer = buildableBuffers[xRegion][zRegion];
// make sure the buffers weren't
// changed while we were running this method
if (currentBuffer == null || (currentBuffer != null && !currentBuffer.building()))
return;
if (setsToRender[xRegion][zRegion] == null)
{
// local position in the vbo and bufferBuilder arrays
BufferBuilder currentBuffer = buildableBuffers[xRegion][zRegion];
// make sure the buffers weren't
// changed while we were running this method
if (currentBuffer == null || (currentBuffer != null && !currentBuffer.building()))
return;
if (setsToRender[xRegion][zRegion] == null)
{
setsToRender[xRegion][zRegion] = new ConcurrentHashMap<LevelPos, MutableBoolean>();
}
ConcurrentMap<LevelPos, MutableBoolean> nodeToRender = (ConcurrentMap<LevelPos, MutableBoolean>) setsToRender[xRegion][zRegion];
Callable<Boolean> dataToRenderThread = () ->
{
lodDim.getDataToRender(
nodeToRender,
regionPos,
playerBlockPosRounded.getX(),
playerBlockPosRounded.getZ());
int posX;
int posZ;
byte detailLevel;
for (LevelPos posToRender : nodeToRender.keySet())
{
if (!nodeToRender.get(posToRender).booleanValue())
{
nodeToRender.remove(posToRender);
continue;
}
nodeToRender.get(posToRender).setFalse();
// skip any chunks that Minecraft is going to render
if (renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()))
{
continue;
}
posX = posToRender.posX;
posZ = posToRender.posZ;
detailLevel = posToRender.detailLevel;
LevelPos chunkPos = posToRender.getConvertedLevelPos(LodUtil.CHUNK_DETAIL_LEVEL);
// skip any chunks that Minecraft is going to render
if (renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkPos.posX, chunkPos.posZ)))
{
continue;
}
try
{
boolean disableFix = false;
if (lodDim.doesDataExist(posToRender.clone()))
{
short[] lodData = lodDim.getData(posToRender);
short[][][] adjData = new short[2][2][];
for (int x : new int[]{0, 1})
{
posToRender.changeParameters(detailLevel, posX + x * 2 - 1, posZ);
if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())
&& (nodeToRender.containsKey(posToRender) || disableFix))
adjData[0][x] = lodDim.getData(posToRender);
}
for (int z : new int[]{0, 1})
{
posToRender.changeParameters(detailLevel, posX, posZ + z * 2 - 1);
if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())
&& (nodeToRender.containsKey(posToRender) || disableFix))
adjData[1][z] = lodDim.getData(posToRender);
}
posToRender.changeParameters(detailLevel, posX, posZ);
LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPos, lodData, adjData,
posToRender, renderer.previousDebugMode);
}
} catch (ArrayIndexOutOfBoundsException e)
{
return false;
}
}// for pos to in list to render
// the thread executed successfully
return true;
};// buffer builder worker thread
nodeToRenderThreads.add(dataToRenderThread);
setsToRender[xRegion][zRegion] = new ConcurrentHashMap<LevelPos, MutableBoolean>();
}
ConcurrentMap<LevelPos, MutableBoolean> nodeToRender = (ConcurrentMap<LevelPos, MutableBoolean>) setsToRender[xRegion][zRegion];
Callable<Boolean> dataToRenderThread = () ->
{
lodDim.getDataToRender(
nodeToRender,
regionPos,
playerBlockPosRounded.getX(),
playerBlockPosRounded.getZ());
int posX;
int posZ;
byte detailLevel;
for (LevelPos posToRender : nodeToRender.keySet())
{
if (!nodeToRender.get(posToRender).booleanValue())
{
nodeToRender.remove(posToRender);
continue;
}
nodeToRender.get(posToRender).setFalse();
// skip any chunks that Minecraft is going to render
if (renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos()))
{
continue;
}
posX = posToRender.posX;
posZ = posToRender.posZ;
detailLevel = posToRender.detailLevel;
LevelPos chunkPos = posToRender.getConvertedLevelPos(LodUtil.CHUNK_DETAIL_LEVEL);
// skip any chunks that Minecraft is going to render
if (renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkPos.posX, chunkPos.posZ)))
{
continue;
}
try
{
boolean disableFix = false;
if (lodDim.doesDataExist(posToRender.clone()))
{
short[] lodData = lodDim.getData(posToRender);
short[][][] adjData = new short[2][2][];
for (int x : new int[]{0, 1})
{
posToRender.changeParameters(detailLevel, posX + x * 2 - 1, posZ);
if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())
&& (nodeToRender.containsKey(posToRender) || disableFix))
adjData[0][x] = lodDim.getData(posToRender);
}
for (int z : new int[]{0, 1})
{
posToRender.changeParameters(detailLevel, posX, posZ + z * 2 - 1);
if (!renderer.vanillaRenderedChunks.contains(posToRender.getChunkPos())
&& (nodeToRender.containsKey(posToRender) || disableFix))
adjData[1][z] = lodDim.getData(posToRender);
}
posToRender.changeParameters(detailLevel, posX, posZ);
LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, playerBlockPos, lodData, adjData,
posToRender, renderer.previousDebugMode);
}
} catch (ArrayIndexOutOfBoundsException e)
{
return false;
}
}// for pos to in list to render
// the thread executed successfully
return true;
};// buffer builder worker thread
nodeToRenderThreads.add(dataToRenderThread);
}// region z
}// region z
long renderStart = System.currentTimeMillis();
@@ -358,7 +355,7 @@ public class LodBufferBuilder
* <p>
* Synchronized to prevent multiple moves happening on top of each other.
*/
public synchronized void move(RegionPos regionOffset,int width)
public synchronized void move(RegionPos regionOffset, int width)
{
int xOffset = regionOffset.x;
int zOffset = regionOffset.z;
@@ -215,7 +215,7 @@ public class LodNodeGenWorker implements IWorker
break;
}
lodRenderer.regenerateLODsNextFrame();
//lodRenderer.regenerateLODsNextFrame();
/*
boolean dataExistence = lodDim.doesDataExist(new LevelPos((byte) 3, pos.x, pos.z));
@@ -70,6 +70,7 @@ public class LodDimension
public volatile LodRegion regions[][];
public volatile boolean isRegionDirty[][];
public volatile boolean regen[][];
public volatile boolean regenDimension = false;
private volatile RegionPos center;
private volatile ChunkPos lastGenChunk;
@@ -419,6 +420,7 @@ public class LodDimension
regions[x][z] = new LodRegion(levelToGen, regionPos, generationMode);
}
regen[x][z] = true;
regenDimension = true;
} else if (region.getMinDetailLevel() > levelToGen)
{
@@ -461,6 +463,7 @@ public class LodDimension
int zIndex = (regionPos.z - center.z) + halfWidth;
isRegionDirty[xIndex][zIndex] = true;
regen[xIndex][zIndex] = true;
regenDimension = true;
} catch (ArrayIndexOutOfBoundsException e)
{
// This method was probably called when the dimension was changing size.
@@ -23,6 +23,7 @@ import java.nio.FloatBuffer;
import java.util.HashSet;
import java.util.Iterator;
import com.seibel.lod.objects.LevelPos.LevelPos;
import net.minecraft.world.chunk.Chunk;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
@@ -124,11 +125,8 @@ public class LodRenderer
/**
* This is used to determine if the LODs should be regenerated
*/
private int prevChunkX = 0;
/**
* This is used to determine if the LODs should be regenerated
*/
private int prevChunkZ = 0;
private LevelPos previousPos = new LevelPos((byte) 0,0,0);
private static long prevTime = 0;
/**
* This is used to determine if the LODs should be regenerated
*/
@@ -197,27 +195,34 @@ public class LodRenderer
ClientPlayerEntity player = mc.player;
// should LODs be regenerated?
if ((int) player.getX() / LodUtil.CHUNK_WIDTH != prevChunkX ||
(int) player.getZ() / LodUtil.CHUNK_WIDTH != prevChunkZ ||
ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.lodChunkRenderDistance.get() ||
prevFogDistance != LodConfig.CLIENT.fogDistance.get())
long newTime = System.currentTimeMillis();
if(newTime - prevTime > 5000)
{
// yes
regen = true;
prevChunkX = (int) player.getX() / LodUtil.CHUNK_WIDTH;
prevChunkZ = (int) player.getZ() / LodUtil.CHUNK_WIDTH;
prevFogDistance = LodConfig.CLIENT.fogDistance.get();
vanillaRenderedChunks.clear();
} else
{
// nope, the player hasn't moved, the
// render distance hasn't changed, and
// the dimension is the same
if (previousPos.detailLevel == 0 ||
player.xChunk != previousPos.posX ||
player.zChunk != previousPos.posZ ||
ClientProxy.previousLodRenderDistance != LodConfig.CLIENT.lodChunkRenderDistance.get() ||
prevFogDistance != LodConfig.CLIENT.fogDistance.get())
{
System.out.println("changing " + previousPos);
// yes
regen = true;
previousPos.changeParameters((byte) 4, player.xChunk, player.zChunk);
prevFogDistance = LodConfig.CLIENT.fogDistance.get();
vanillaRenderedChunks.clear();
}
if(lodDim.regenDimension)
{
regen = true;
lodDim.regenDimension = false;
}
prevTime = newTime;
System.out.println(newTime - prevTime);
}
// did the user change the debug setting?
if (LodConfig.CLIENT.debugMode.get() != previousDebugMode)
{
@@ -239,7 +244,6 @@ public class LodRenderer
if(!vanillaRenderedChunks.contains(pos))
{
vanillaRenderedChunks.add(pos);
System.out.println(pos);
lodDim.setToRegen(pos.getRegionX(),pos.getRegionZ());
}
}
@@ -264,6 +268,7 @@ public class LodRenderer
// (this is to prevent thread conflicts)
if (regen && !lodBufferBuilder.generatingBuffers && !lodBufferBuilder.newBuffersAvaliable())
{
System.out.println("redrawing");
// generate the LODs on a separate thread to prevent stuttering or freezing
lodBufferBuilder.generateLodBuffersAsync(this, lodDim, player.blockPosition(), Math.floorMod((int) player.xRot,360), Math.floorMod((int) player.yRot,360), numbChunksWide);