Optimized the regen
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user