resolved many warnings and applied autoformat in affected files

This commit is contained in:
cola98765
2021-10-07 10:36:30 +02:00
parent a6f3c2478e
commit 6deca8e235
7 changed files with 274 additions and 337 deletions
@@ -15,24 +15,9 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.builders.bufferBuilding;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL15C;
import org.lwjgl.opengl.GL45;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.seibel.lod.builders.bufferBuilding.lodTemplates.Box;
import com.seibel.lod.config.LodConfig;
@@ -44,18 +29,27 @@ import com.seibel.lod.objects.RegionPos;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.proxy.GlProxy;
import com.seibel.lod.render.LodRenderer;
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.util.ThreadMapUtil;
import com.seibel.lod.util.*;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.client.renderer.vertex.VertexBuffer;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL15C;
import org.lwjgl.opengl.GL45;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock;
/**
* This object is used to create NearFarBuffer objects.
@@ -135,7 +129,7 @@ public class LodBufferBuilder
/**
* this is used to prevent multiple threads creating, destroying, or using the buffers at the same time
*/
private ReentrantLock bufferLock = new ReentrantLock();
private final ReentrantLock bufferLock = new ReentrantLock();
private volatile Box[][] boxCache;
private volatile PosToRenderContainer[][] setsToRender;
@@ -322,9 +316,9 @@ public class LodBufferBuilder
chunkZdist = LevelPosUtil.getChunkPos(detailLevel, zAdj) - playerChunkPos.z;
if (posToRender.contains(detailLevel, xAdj, zAdj)
&& (gameChunkRenderDistance < Math.abs(chunkXdist)
|| gameChunkRenderDistance < Math.abs(chunkZdist)
|| !(vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1]
&& (!LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1) || smallRenderDistance))))
|| gameChunkRenderDistance < Math.abs(chunkZdist)
|| !(vanillaRenderedChunks[chunkXdist + gameChunkRenderDistance + 1][chunkZdist + gameChunkRenderDistance + 1]
&& (!LodUtil.isBorderChunk(vanillaRenderedChunks, chunkXdist + gameChunkRenderDistance + 1, chunkZdist + gameChunkRenderDistance + 1) || smallRenderDistance))))
{
for (int verticalIndex = 0; verticalIndex < lodDim.getMaxVerticalData(detailLevel, xAdj, zAdj); verticalIndex++)
{
@@ -357,7 +351,7 @@ public class LodBufferBuilder
} // for pos to in list to render
// the thread executed successfully
// the thread executed successfully
return true;
};
@@ -390,7 +384,7 @@ public class LodBufferBuilder
long buildTime = endTime - startTime;
@SuppressWarnings("unused")
long executeTime = executeEnd - executeStart;
// ClientProxy.LOGGER.info("Thread Build time: " + buildTime + " ms" + '\n' +
// "thread execute time: " + executeTime + " ms");
@@ -469,7 +463,7 @@ public class LodBufferBuilder
}
else
{
numberOfBuffers = (int) Math.ceil(memoryRequired / BUFFER_MAX_CAPACITY) + 1;
numberOfBuffers = (int) memoryRequired / BUFFER_MAX_CAPACITY + 1;
memoryRequired = BUFFER_MAX_CAPACITY;
bufferSize[x][z] = numberOfBuffers;
buildableBuffers[x][z] = new BufferBuilder[numberOfBuffers];
@@ -483,8 +477,8 @@ public class LodBufferBuilder
buildableVbos[x][z][i] = new VertexBuffer(LodRenderer.LOD_VERTEX_FORMAT);
drawableVbos[x][z][i] = new VertexBuffer(LodRenderer.LOD_VERTEX_FORMAT);
// // buffer storage
// GL15.glDeleteBuffers(buildableVbos[x][z][i].id);
// GL15.glDeleteBuffers(drawableVbos[x][z][i].id);
@@ -619,9 +613,9 @@ public class LodBufferBuilder
{
// this is how many points will be rendered
vbo.vertexCount = (uploadBuffer.remaining() / vbo.format.getVertexSize());
// // buffer mapping //
// // no stutter 50% GPU useage
// // stores everything in system memory instead of GPU memory
@@ -656,11 +650,11 @@ public class LodBufferBuilder
// GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
// GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
// }
// // bufferstorage //
// // to test: uncomment the bufferstorage lines in setupBuffers as well
// // then reboot the game
@@ -694,7 +688,7 @@ public class LodBufferBuilder
// GL45.glBindBuffer(GL45.GL_ARRAY_BUFFER, 0);
// }
@@ -704,18 +698,18 @@ public class LodBufferBuilder
GL45.glBindBuffer(GL45.GL_ARRAY_BUFFER, vbo.id);
long size = GL45.glGetBufferParameteri64(GL45.GL_ARRAY_BUFFER, GL45.GL_BUFFER_SIZE);
if (size < uploadBuffer.capacity() * 4)
if (size < uploadBuffer.capacity() * 4L)
{
GL45.glBufferData(GL45.GL_ARRAY_BUFFER, uploadBuffer.capacity() * 5, GL45.GL_STREAM_DRAW);
GL45.glBufferData(GL45.GL_ARRAY_BUFFER, uploadBuffer.capacity() * 5L, GL45.GL_STREAM_DRAW);
ClientProxy.LOGGER.info("expand buffer: " + size + " -> " + (uploadBuffer.capacity() * 4));
}
GL45.glBufferSubData(GL45.GL_ARRAY_BUFFER, 0, uploadBuffer);
GL15.glUnmapBuffer(GL15.GL_ARRAY_BUFFER);
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15C.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
// // old method - bufferData
// // bad stuttering 12% GPU usage
//
@@ -759,7 +753,7 @@ public class LodBufferBuilder
/**
* A simple container to pass multiple objects back in the getVertexBuffers method.
*/
public class VertexBuffersAndOffset
public static class VertexBuffersAndOffset
{
public VertexBuffer[][][] vbos;
public ChunkPos drawableCenterChunkPos;
@@ -1,20 +1,19 @@
package com.seibel.lod.builders.bufferBuilding.lodTemplates;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DebugMode;
import com.seibel.lod.util.ColorUtil;
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.vector.Vector3i;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/**
* Similar to Minecraft's AxisAlignedBoundingBox.
*
@@ -37,57 +36,56 @@ public class Box
public static final int VOID_FACE = 0;
/** The six cardinal directions */
public static final Direction[] DIRECTIONS = new Direction[]{
public static final Direction[] DIRECTIONS = new Direction[] {
Direction.UP,
Direction.DOWN,
Direction.WEST,
Direction.EAST,
Direction.NORTH,
Direction.SOUTH};
Direction.SOUTH };
/** North, South, East, West */
public static final Direction[] ADJ_DIRECTIONS = new Direction[]{
public static final Direction[] ADJ_DIRECTIONS = new Direction[] {
Direction.EAST,
Direction.WEST,
Direction.SOUTH,
Direction.NORTH};
Direction.NORTH };
/**
* All the faces and vertices of a cube. This is used to extract the vertex from the column
*/
@SuppressWarnings("serial")
public static final Map<Direction, int[][]> DIRECTION_VERTEX_MAP = new HashMap<Direction, int[][]>()
{{
put(Direction.UP, new int[][]{
{0, 1, 0},
{0, 1, 1},
{1, 1, 1},
{1, 1, 0}});
put(Direction.DOWN, new int[][]{
{1, 0, 0},
{1, 0, 1},
{0, 0, 1},
{0, 0, 0}});
put(Direction.EAST, new int[][]{
{1, 1, 0},
{1, 1, 1},
{1, 0, 1},
{1, 0, 0}});
put(Direction.WEST, new int[][]{
{0, 0, 0},
{0, 0, 1},
{0, 1, 1},
{0, 1, 0}});
put(Direction.SOUTH, new int[][]{
{1, 0, 1},
{1, 1, 1},
{0, 1, 1},
{0, 0, 1}});
put(Direction.NORTH, new int[][]{
{0, 0, 0},
{0, 1, 0},
{1, 1, 0},
{1, 0, 0}});
put(Direction.UP, new int[][] {
{ 0, 1, 0 },
{ 0, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 0 } });
put(Direction.DOWN, new int[][] {
{ 1, 0, 0 },
{ 1, 0, 1 },
{ 0, 0, 1 },
{ 0, 0, 0 } });
put(Direction.EAST, new int[][] {
{ 1, 1, 0 },
{ 1, 1, 1 },
{ 1, 0, 1 },
{ 1, 0, 0 } });
put(Direction.WEST, new int[][] {
{ 0, 0, 0 },
{ 0, 0, 1 },
{ 0, 1, 1 },
{ 0, 1, 0 } });
put(Direction.SOUTH, new int[][] {
{ 1, 0, 1 },
{ 1, 1, 1 },
{ 0, 1, 1 },
{ 0, 0, 1 } });
put(Direction.NORTH, new int[][] {
{ 0, 0, 0 },
{ 0, 1, 0 },
{ 1, 1, 0 },
{ 1, 0, 0 } });
}};
@@ -95,15 +93,14 @@ public class Box
* This indicate which position is invariable in the DIRECTION_VERTEX_MAP.
* Is used to extract the vertex
*/
@SuppressWarnings("serial")
public static final Map<Direction, int[]> FACE_DIRECTION = new HashMap<Direction, int[]>()
{{
put(Direction.UP, new int[]{Y, MAX});
put(Direction.DOWN, new int[]{Y, MIN});
put(Direction.EAST, new int[]{X, MAX});
put(Direction.WEST, new int[]{X, MIN});
put(Direction.SOUTH, new int[]{Z, MAX});
put(Direction.NORTH, new int[]{Z, MIN});
put(Direction.UP, new int[] { Y, MAX });
put(Direction.DOWN, new int[] { Y, MIN });
put(Direction.EAST, new int[] { X, MAX });
put(Direction.WEST, new int[] { X, MIN });
put(Direction.SOUTH, new int[] { Z, MAX });
put(Direction.NORTH, new int[] { Z, MIN });
}};
@@ -159,7 +156,6 @@ public class Box
/** creates a empty box */
@SuppressWarnings("serial")
public Box()
{
boxOffset = new int[3];
@@ -248,7 +244,7 @@ public class Box
playerPos = MinecraftWrapper.INSTANCE.getPlayer().blockPosition();
for (Direction direction : DIRECTIONS)
{
if (direction == Direction.DOWN || direction == Direction.WEST || direction == Direction.NORTH)
if (direction == Direction.DOWN || direction == Direction.WEST || direction == Direction.NORTH)
{
culling[DIRECTION_INDEX.get(direction)] = playerPos.get(direction.getAxis()) > getFacePos(direction) + cullingDistance;
}
@@ -304,7 +300,7 @@ public class Box
{
singleAdjDataPoint = dataPoint[i];
if(DataPointUtil.isVoid(singleAdjDataPoint) || !DataPointUtil.doesItExist(singleAdjDataPoint))
if (DataPointUtil.isVoid(singleAdjDataPoint) || !DataPointUtil.doesItExist(singleAdjDataPoint))
break;
height = DataPointUtil.getHeight(singleAdjDataPoint);
@@ -385,7 +381,7 @@ public class Box
}
}
if(allAbove)
if (allAbove)
{
adjHeight.get(direction)[0] = getMaxY();
adjDepth.get(direction)[0] = getMinY();
@@ -15,15 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.builders.lodBuilding;
import java.awt.Color;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
package com.seibel.lod.builders.lodBuilding;
import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DistanceGenerationMode;
@@ -32,26 +25,9 @@ import com.seibel.lod.enums.VerticalQuality;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodRegion;
import com.seibel.lod.objects.LodWorld;
import com.seibel.lod.util.ColorUtil;
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.util.ThreadMapUtil;
import com.seibel.lod.util.*;
import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.block.AbstractPlantBlock;
import net.minecraft.block.AbstractTopPlantBlock;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks;
import net.minecraft.block.BushBlock;
import net.minecraft.block.FlowerBlock;
import net.minecraft.block.GrassBlock;
import net.minecraft.block.IGrowable;
import net.minecraft.block.LeavesBlock;
import net.minecraft.block.TallGrassBlock;
import net.minecraft.block.*;
import net.minecraft.block.material.MaterialColor;
import net.minecraft.client.renderer.model.BakedQuad;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
@@ -71,6 +47,14 @@ import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.gen.Heightmap;
import net.minecraftforge.client.model.data.ModelDataMap;
import java.awt.*;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* This object is in charge of creating Lod related objects. (specifically: Lod
* World, Dimension, and Region objects)
@@ -81,9 +65,9 @@ import net.minecraftforge.client.model.data.ModelDataMap;
*/
public class LodBuilder
{
private static MinecraftWrapper mc = MinecraftWrapper.INSTANCE;
private static final MinecraftWrapper mc = MinecraftWrapper.INSTANCE;
private ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName()));
private final ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName()));
public static final Direction[] directions = new Direction[] { Direction.UP, Direction.EAST, Direction.SOUTH, Direction.WEST, Direction.NORTH, Direction.DOWN };
public static final int CHUNK_DATA_WIDTH = LodUtil.CHUNK_WIDTH;
@@ -115,19 +99,14 @@ public class LodBuilder
public LodBuilder()
{
}
public void generateLodNodeAsync(IChunk chunk, LodWorld lodWorld, IWorld world)
{
generateLodNodeAsync(chunk, lodWorld, world, DistanceGenerationMode.SERVER);
}
public void generateLodNodeAsync(IChunk chunk, LodWorld lodWorld, IWorld world, DistanceGenerationMode generationMode)
{
if (lodWorld == null || !lodWorld.getIsWorldLoaded())
@@ -245,7 +224,7 @@ public class LodBuilder
singleData,
false);
break;
case VOXEL:
long[] dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ, endX, endZ);
data = DataPointUtil.mergeMultiData(dataToMergeVertical, DataPointUtil.worldHeight, DetailDistanceUtil.getMaxVerticalData(detailLevel));
@@ -366,35 +345,35 @@ public class LodBuilder
private short determineBottomPointFrom(IChunk chunk, LodBuilderConfig config, int xRel, int zRel, int yAbs, BlockPos.Mutable blockPos)
{
short depth = DEFAULT_DEPTH;
if (config.useHeightmap)
/*if (config.useHeightmap)
{
// when using the generated heightmap there is no data about the lowest point
depth = 0;
depth = 0; //DEFAULT_DEPTH == 0
}
else
{*/
boolean voidData = true;
ChunkSection[] chunkSections = chunk.getSections();
for (int sectionIndex = chunkSections.length - 1; sectionIndex >= 0; sectionIndex--)
{
boolean voidData = true;
ChunkSection[] chunkSections = chunk.getSections();
for (int sectionIndex = chunkSections.length - 1; sectionIndex >= 0; sectionIndex--)
for (int yRel = CHUNK_DATA_WIDTH - 1; yRel >= 0; yRel--)
{
for (int yRel = CHUNK_DATA_WIDTH - 1; yRel >= 0; yRel--)
{
if (sectionIndex * CHUNK_DATA_WIDTH + yRel > yAbs)
continue;
blockPos.set(chunk.getPos().getMinBlockX() + xRel, sectionIndex * CHUNK_DATA_WIDTH + yRel, chunk.getPos().getMinBlockZ() + zRel);
if (!isLayerValidLodPoint(chunk, blockPos))
{
depth = (short) (sectionIndex * CHUNK_DATA_WIDTH + yRel + 1);
voidData = false;
break;
}
}
if (sectionIndex * CHUNK_DATA_WIDTH + yRel > yAbs)
continue;
if (!voidData)
blockPos.set(chunk.getPos().getMinBlockX() + xRel, sectionIndex * CHUNK_DATA_WIDTH + yRel, chunk.getPos().getMinBlockZ() + zRel);
if (!isLayerValidLodPoint(chunk, blockPos))
{
depth = (short) (sectionIndex * CHUNK_DATA_WIDTH + yRel + 1);
voidData = false;
break;
}
}
if (!voidData)
break;
}
//}
return depth;
}
@@ -405,9 +384,7 @@ public class LodBuilder
{
short height = DEFAULT_HEIGHT;
if (config.useHeightmap)
{
height = (short) chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP).getFirstAvailable(xRel, zRel);
}
else
{
boolean voidData = true;
@@ -509,30 +486,30 @@ public class LodBuilder
{
ChunkSection[] chunkSections = chunk.getSections();
short depth = DEFAULT_DEPTH;
if (config.useHeightmap)
/*if (config.useHeightmap)
{
depth = 0;
depth = 0; //DEFAULT_DEPTH == 0
}
else
{*/
boolean found = false;
for (int sectionIndex = 0; sectionIndex < chunkSections.length; sectionIndex++)
{
boolean found = false;
for (int sectionIndex = 0; sectionIndex < chunkSections.length; sectionIndex++)
for (int yRel = 0; yRel < CHUNK_DATA_WIDTH; yRel++)
{
for (int yRel = 0; yRel < CHUNK_DATA_WIDTH; yRel++)
blockPos.set(chunk.getPos().getMinBlockX() + xRel, sectionIndex * CHUNK_DATA_WIDTH + yRel, chunk.getPos().getMinBlockZ() + zRel);
if (isLayerValidLodPoint(chunk, blockPos))
{
blockPos.set(chunk.getPos().getMinBlockX() + xRel, sectionIndex * CHUNK_DATA_WIDTH + yRel, chunk.getPos().getMinBlockZ() + zRel);
if (isLayerValidLodPoint(chunk, blockPos))
{
depth = (short) (sectionIndex * CHUNK_DATA_WIDTH + yRel);
found = true;
break;
}
}
if (found)
depth = (short) (sectionIndex * CHUNK_DATA_WIDTH + yRel);
found = true;
break;
}
}
if (found)
break;
}
//}
return depth;
}
@@ -544,9 +521,7 @@ public class LodBuilder
{
short height = DEFAULT_HEIGHT;
if (config.useHeightmap)
{
height = (short) chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP).getFirstAvailable(xRel, zRel);
}
else
{
boolean voidData = true;
@@ -610,7 +585,7 @@ public class LodBuilder
private int getLightValue(IChunk chunk, BlockPos.Mutable blockPos, boolean hasCeiling, boolean hasSkyLight, boolean topBlock)
{
int skyLight;
int blockLight = 0;
int blockLight;
if (mc.getClientWorld() == null)
return 0;
@@ -627,19 +602,13 @@ public class LodBuilder
if (!hasSkyLight && hasCeiling)
{
skyLight = 0;
}
else if (topBlock)
{
skyLight = DEFAULT_MAX_LIGHT;
}
else
{
if (chunk.isLightCorrect())
{
skyLight = world.getBrightness(LightType.SKY, blockPos);
}
else
{
// we don't know what the light here is,
@@ -747,10 +716,8 @@ public class LodBuilder
if (count == 0)
{
// this block is entirely transparent
color = 0;
}
else
{
// determine the average color
@@ -828,25 +795,17 @@ public class LodBuilder
if (toTint.get(blockState.getBlock()).booleanValue())
{
if (useLeafTint(blockState.getBlock()))
{
// leaves
colorInt = ColorUtil.multiplyRGBcolors(biome.getFoliageColor() | 0xFF000000, blockColor);
}
else if (useGrassTint(blockState.getBlock()))
{
// grass and green plants
colorInt = ColorUtil.multiplyRGBcolors(biome.getGrassColor(x, z) | 0xFF000000, blockColor);
}
else if (useWaterTint(blockState.getBlock()))
{
// water
colorInt = ColorUtil.multiplyRGBcolors(biome.getWaterColor() | 0xFF000000, blockColor);
}
}
else
{
colorInt = blockColor;
}
return colorInt;
}
@@ -907,22 +866,23 @@ public class LodBuilder
tmp = tmp.darker();
colorInt = LodUtil.colorToInt(tmp);
break;
}
return colorInt;
}
public static final ConcurrentMap<Block, Boolean> notFullBlock = new ConcurrentHashMap<>();
public static final ConcurrentMap<Block, Boolean> smallBlock = new ConcurrentHashMap<>();
/**
* Is the block at the given blockPos a valid LOD point?
*/
private boolean isLayerValidLodPoint(IChunk chunk, BlockPos.Mutable blockPos)
{
BlockState blockState = chunk.getBlockState(blockPos);
if (blockState != null)
{
// TODO this code is dead since avoidSmallBlock and onlyUseFullBlock
@@ -931,9 +891,9 @@ public class LodBuilder
if (avoidSmallBlock || avoidNonFullBlock)
{
if (!smallBlock.containsKey(blockState.getBlock())
|| smallBlock.get(blockState.getBlock()) == null
|| !notFullBlock.containsKey(blockState.getBlock())
|| notFullBlock.get(blockState.getBlock()) == null
|| smallBlock.get(blockState.getBlock()) == null
|| !notFullBlock.containsKey(blockState.getBlock())
|| notFullBlock.get(blockState.getBlock()) == null
)
{
VoxelShape voxelShape = blockState.getShape(chunk, blockPos);
@@ -942,7 +902,7 @@ public class LodBuilder
notFullBlock.put(blockState.getBlock(), false);
smallBlock.put(blockState.getBlock(), false);
}
if (!voxelShape.isEmpty())
{
AxisAlignedBB bbox = voxelShape.bounds();
@@ -953,34 +913,31 @@ public class LodBuilder
notFullBlock.put(blockState.getBlock(), true);
else
notFullBlock.put(blockState.getBlock(), false);
if (xWidth < 0.7 && zWidth < 0.7 && yWidth < 0.7)
smallBlock.put(blockState.getBlock(), true);
else
smallBlock.put(blockState.getBlock(), false);
} else
}
else
{
notFullBlock.put(blockState.getBlock(), false);
smallBlock.put(blockState.getBlock(), false);
}
}
if (notFullBlock.get(blockState.getBlock()) && avoidNonFullBlock)
{
return false;
}
if (smallBlock.get(blockState.getBlock()) && avoidSmallBlock)
{
return false;
}
}
return blockState.getBlock() != Blocks.AIR
&& blockState.getBlock() != Blocks.CAVE_AIR
&& blockState.getBlock() != Blocks.BARRIER;
&& blockState.getBlock() != Blocks.CAVE_AIR
&& blockState.getBlock() != Blocks.BARRIER;
}
return false;
}
}
@@ -15,16 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.builders.worldGeneration;
import java.util.ConcurrentModificationException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
package com.seibel.lod.builders.worldGeneration;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.seibel.lod.builders.lodBuilding.LodBuilder;
@@ -33,9 +25,7 @@ import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
import net.minecraft.util.math.ChunkPos;
@@ -48,13 +38,7 @@ import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.gen.ChunkGenerator;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.gen.blockstateprovider.WeightedBlockStateProvider;
import net.minecraft.world.gen.feature.BlockClusterFeatureConfig;
import net.minecraft.world.gen.feature.ConfiguredFeature;
import net.minecraft.world.gen.feature.DecoratedFeatureConfig;
import net.minecraft.world.gen.feature.FeatureSpread;
import net.minecraft.world.gen.feature.FeatureSpreadConfig;
import net.minecraft.world.gen.feature.IceAndSnowFeature;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.feature.*;
import net.minecraft.world.gen.placement.ConfiguredPlacement;
import net.minecraft.world.gen.placement.DecoratedPlacementConfig;
import net.minecraft.world.gen.placement.IPlacementConfig;
@@ -64,6 +48,15 @@ import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.server.ServerWorldLightManager;
import net.minecraftforge.common.WorldWorkerManager.IWorker;
import java.util.ConcurrentModificationException;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Supplier;
/**
* This is used to generate a LodChunk at a given ChunkPos.
*
@@ -75,13 +68,13 @@ public class LodNodeGenWorker implements IWorker
public static ExecutorService genThreads = Executors.newFixedThreadPool(LodConfig.CLIENT.threading.numberOfWorldGenerationThreads.get(), new ThreadFactoryBuilder().setNameFormat("Gen-Worker-Thread-%d").build());
private boolean threadStarted = false;
private LodChunkGenThread thread;
private final LodChunkGenThread thread;
/** If a configured feature fails for whatever reason,
* add it to this list, this is to hopefully remove any
* features that could cause issues down the line. */
private static ConcurrentHashMap<Integer, ConfiguredFeature<?, ?>> configuredFeaturesToAvoid = new ConcurrentHashMap<>();
private static final ConcurrentHashMap<Integer, ConfiguredFeature<?, ?>> configuredFeaturesToAvoid = new ConcurrentHashMap<>();
@@ -101,9 +94,9 @@ public class LodNodeGenWorker implements IWorker
if (newServerWorld == null)
throw new IllegalArgumentException("LodChunkGenThread requires a non-null ServerWorld");
thread = new LodChunkGenThread(newPos, newGenerationMode,
newLodBuilder,
newLodDimension, newServerWorld);
@@ -149,14 +142,14 @@ public class LodNodeGenWorker implements IWorker
private class LodChunkGenThread implements Runnable
private static class LodChunkGenThread implements Runnable
{
public final ServerWorld serverWorld;
public final LodDimension lodDim;
public final DistanceGenerationMode generationMode;
public final LodBuilder lodBuilder;
private ChunkPos pos;
private final ChunkPos pos;
public LodChunkGenThread(ChunkPos newPos, DistanceGenerationMode newGenerationMode,
LodBuilder newLodBuilder,
@@ -177,12 +170,12 @@ public class LodNodeGenWorker implements IWorker
// only generate LodChunks if they can
// be added to the current LodDimension
/**TODO i must disable this if, i will find a way to replace it*/
/* TODO i must disable this if, i will find a way to replace it */
if (lodDim.regionIsInRange(pos.x / LodUtil.REGION_WIDTH_IN_CHUNKS, pos.z / LodUtil.REGION_WIDTH_IN_CHUNKS))
{
// long startTime = System.currentTimeMillis();
switch(generationMode)
switch (generationMode)
{
case NONE:
// don't generate
@@ -217,7 +210,7 @@ public class LodNodeGenWorker implements IWorker
*/
// shows the pool size, active threads, queued tasks and completed tasks
// ClientProxy.LOGGER.info(genThreads.toString());
// long endTime = System.currentTimeMillis();
// System.out.println(endTime - startTime);
@@ -271,20 +264,20 @@ public class LodNodeGenWorker implements IWorker
// add fake heightmap data so our LODs aren't at height 0
Heightmap heightmap = new Heightmap(chunk, LodUtil.DEFAULT_HEIGHTMAP);
for(int x = 0; x < LodUtil.CHUNK_WIDTH && !inTheEnd; x++)
for (int x = 0; x < LodUtil.CHUNK_WIDTH && !inTheEnd; x++)
{
for(int z = 0; z < LodUtil.CHUNK_WIDTH && !inTheEnd; z++)
for (int z = 0; z < LodUtil.CHUNK_WIDTH && !inTheEnd; z++)
{
if (simulateHeight)
{
// these heights are of course aren't super accurate,
// they are just to simulate height data where there isn't any
switch(chunk.getBiomes().getNoiseBiome(x >> 2, seaLevel >> 2, z >> 2).getBiomeCategory())
switch (chunk.getBiomes().getNoiseBiome(x >> 2, seaLevel >> 2, z >> 2).getBiomeCategory())
{
case NETHER:
heightmap.setHeight(x, z, serverWorld.getHeight() / 2);
break;
case EXTREME_HILLS:
heightmap.setHeight(x, z, seaLevel + 30);
break;
@@ -300,24 +293,24 @@ public class LodNodeGenWorker implements IWorker
case NONE:
heightmap.setHeight(x, z, 0);
break;
case OCEAN:
case RIVER:
heightmap.setHeight(x, z, seaLevel);
break;
case THEEND:
inTheEnd = true;
break;
// DESERT
// FOREST
// ICY
// MUSHROOM
// SAVANNA
// SWAMP
// TAIGA
// PLAINS
// DESERT
// FOREST
// ICY
// MUSHROOM
// SAVANNA
// SWAMP
// TAIGA
// PLAINS
default:
heightmap.setHeight(x, z, seaLevel + 10);
break;
@@ -346,8 +339,8 @@ public class LodNodeGenWorker implements IWorker
// generates the same and it looks really bad.
lodBuilder.generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig(true, true, false));
}
// long startTime = System.currentTimeMillis();
// long endTime = System.currentTimeMillis();
// System.out.println(endTime - startTime);
@@ -445,9 +438,9 @@ public class LodNodeGenWorker implements IWorker
{
List<List<Supplier<ConfiguredFeature<?, ?>>>> featuresForState = biome.generationSettings.features();
for(int featureStateToGenerate = 0; featureStateToGenerate < featuresForState.size(); featureStateToGenerate++)
for (int featureStateToGenerate = 0; featureStateToGenerate < featuresForState.size(); featureStateToGenerate++)
{
for(Supplier<ConfiguredFeature<?, ?>> featureSupplier : featuresForState.get(featureStateToGenerate))
for (Supplier<ConfiguredFeature<?, ?>> featureSupplier : featuresForState.get(featureStateToGenerate))
{
ConfiguredFeature<?, ?> configuredFeature = featureSupplier.get();
@@ -460,7 +453,7 @@ public class LodNodeGenWorker implements IWorker
{
configuredFeature.place(lodServerWorld, chunkGen, serverWorld.random, chunk.getPos().getWorldPosition());
}
catch(ConcurrentModificationException e)
catch (ConcurrentModificationException e)
{
// This will happen. I'm not sure what to do about it
// except pray that it doesn't effect the normal world generation
@@ -480,7 +473,7 @@ public class LodNodeGenWorker implements IWorker
configuredFeaturesToAvoid.put(configuredFeature.hashCode(), configuredFeature);
// ClientProxy.LOGGER.info(configuredFeaturesToAvoid.mappingCount());
}
catch(UnsupportedOperationException e)
catch (UnsupportedOperationException e)
{
// This will happen when the LodServerWorld
// isn't able to return something that a feature
@@ -490,7 +483,7 @@ public class LodNodeGenWorker implements IWorker
configuredFeaturesToAvoid.put(configuredFeature.hashCode(), configuredFeature);
// ClientProxy.LOGGER.info(configuredFeaturesToAvoid.mappingCount());
}
catch(Exception e)
catch (Exception e)
{
// I'm not sure what happened, print to the log
@@ -549,12 +542,12 @@ public class LodNodeGenWorker implements IWorker
placementConfig = new FeatureSpreadConfig(oldSpread);
}
else if(oldConfigClass == DecoratedPlacementConfig.class)
else if (oldConfigClass == DecoratedPlacementConfig.class)
{
DecoratedPlacementConfig oldPlacementConfig = (DecoratedPlacementConfig) config.decorator.config();
placementConfig = new DecoratedPlacementConfig(oldPlacementConfig.inner(), oldPlacementConfig.outer());
}
else if(oldConfigClass == NoiseDependant.class)
else if (oldConfigClass == NoiseDependant.class)
{
NoiseDependant oldPlacementConfig = (NoiseDependant) config.decorator.config();
placementConfig = new NoiseDependant(oldPlacementConfig.noiseLevel, oldPlacementConfig.belowNoise, oldPlacementConfig.aboveNoise);
@@ -588,9 +581,18 @@ public class LodNodeGenWorker implements IWorker
builder.xspread(config.xspread);
builder.yspread(config.yspread);
builder.zspread(config.zspread);
if(config.canReplace) { builder.canReplace(); }
if(config.needWater) { builder.needWater(); }
if(config.project) { builder.noProjection(); }
if (config.canReplace)
{
builder.canReplace();
}
if (config.needWater)
{
builder.needWater();
}
if (config.project)
{
builder.noProjection();
}
builder.tries(config.tries);
@@ -15,37 +15,27 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.handlers;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.VerticalQuality;
import com.seibel.lod.objects.*;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.VerticalQuality;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodRegion;
import com.seibel.lod.objects.RegionPos;
import com.seibel.lod.objects.SingleLevelContainer;
import com.seibel.lod.objects.VerticalLevelContainer;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil;
/**
* This object handles creating LodRegions
* from files and saving LodRegion objects
* to file.
*
*
* @author James Seibel
* @author Cola
* @version 9-25-2021
@@ -230,7 +220,7 @@ public class LodDimensionFileHandler
fileWritingThreadPool.execute(saveDirtyRegionsThread);
}
private Thread saveDirtyRegionsThread = new Thread(() ->
private final Thread saveDirtyRegionsThread = new Thread(() ->
{
try
{
@@ -238,9 +228,9 @@ public class LodDimensionFileHandler
{
for (int j = 0; j < lodDimension.getWidth(); j++)
{
if (lodDimension.GetIsRegionDirty(i,j) && lodDimension.getRegionByArrayIndex(i,j) != null)
if (lodDimension.GetIsRegionDirty(i, j) && lodDimension.getRegionByArrayIndex(i, j) != null)
{
saveRegionToFile(lodDimension.getRegionByArrayIndex(i,j));
saveRegionToFile(lodDimension.getRegionByArrayIndex(i, j));
lodDimension.SetIsRegionDirty(i, j, false);
}
}
@@ -311,7 +301,7 @@ public class LodDimensionFileHandler
// don't write anything, we don't want to accidently
// delete anything the user may want.
return;
}
}
// if we got this far then we are good
// to overwrite the old file
@@ -15,12 +15,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.objects;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
package com.seibel.lod.objects;
import com.seibel.lod.config.LodConfig;
import com.seibel.lod.enums.DistanceGenerationMode;
@@ -28,27 +24,27 @@ import com.seibel.lod.enums.GenerationPriority;
import com.seibel.lod.enums.LodTemplate;
import com.seibel.lod.enums.VerticalQuality;
import com.seibel.lod.handlers.LodDimensionFileHandler;
import com.seibel.lod.util.DataPointUtil;
import com.seibel.lod.util.DetailDistanceUtil;
import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.util.*;
import com.seibel.lod.wrappers.MinecraftWrapper;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.DimensionType;
import net.minecraft.world.server.ServerChunkProvider;
import net.minecraft.world.server.ServerWorld;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* This object holds all loaded LOD regions
* for a given dimension. <Br><Br>
*
*
* <strong>Coordinate Standard: </strong><br>
* Coordinate called posX or posZ are relative LevelPos coordinates <br>
* unless stated otherwise. <br>
*
*
* @author Leonardo Amato
* @author James Seibel
* @version 9-27-2021
@@ -82,13 +78,13 @@ public class LodDimension
private LodDimensionFileHandler fileHandler;
private volatile RegionPos center;
private final RegionPos center;
/** prevents the cutAndExpandThread from expanding at the same location multiple times */
private volatile ChunkPos lastExpandedChunk;
/** prevents the cutAndExpandThread from cutting at the same location multiple times */
private volatile ChunkPos lastCutChunk;
private ExecutorService cutAndExpandThread = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " - Cut and Expand"));
private final ExecutorService cutAndExpandThread = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " - Cut and Expand"));
/**
* Creates the dimension centered at (0,0)
@@ -584,8 +580,8 @@ public class LodDimension
z += dz;
}
break;
case FAR_FIRST:
posToGenerate = new PosToGenerateContainer((byte) 8, maxDataToGenerate, playerBlockPosX, playerBlockPosZ);
@@ -618,11 +614,11 @@ public class LodDimension
/**
* Returns every node that should be rendered based on the position of the player.
*
*
* TODO why isn't posToRender returned? it would make it a bit more clear what is happening
*/
public void getPosToRender(PosToRenderContainer posToRender, RegionPos regionPos, int playerPosX,
int playerPosZ)
int playerPosZ)
{
LodRegion region = getRegion(regionPos.x, regionPos.z);
if (region != null)
@@ -709,7 +705,7 @@ public class LodDimension
/**
* TODO we aren't currently using this, is there a reason for that?
* is this significantly different than regenRegionBuffer?
*
*
* Returns if the buffer at the given array index needs
* to have its buffer resized.
*/
@@ -762,7 +758,7 @@ public class LodDimension
* Loads the region at the given RegionPos from file,
* if a file exists for that region.
*/
public LodRegion getRegionFromFile(RegionPos regionPos, byte detailLevel,
public LodRegion getRegionFromFile(RegionPos regionPos, byte detailLevel,
DistanceGenerationMode generationMode, VerticalQuality verticalQuality)
{
if (fileHandler != null)
@@ -901,17 +897,17 @@ public class LodDimension
int levelToGen = DetailDistanceUtil.getLodDrawDetail(detail);
int size = 1 << (LodUtil.REGION_DETAIL_LEVEL - levelToGen);
int maxVerticalData = DetailDistanceUtil.getMaxVerticalData(detail);
long memoryUse = LodUtil.regionRenderingMemoryUse(x,z,template);
long memoryUse = LodUtil.regionRenderingMemoryUse(x, z, template);
//System.out.println(detail + " " + memoryUse + " " + template.getBufferMemoryForSingleLod(maxVerticalData));
return memoryUse;
//return memoryUse;
}
public boolean GetIsRegionDirty(int i , int j)
public boolean GetIsRegionDirty(int i, int j)
{
return isRegionDirty[i][j];
}
public void SetIsRegionDirty(int i, int j, boolean val)
{
isRegionDirty[i][j] = val;
@@ -13,7 +13,7 @@ import java.util.concurrent.ConcurrentMap;
* Holds data used by specific threads so
* the data doesn't have to be recreated every
* time it is needed.
*
*
* @author Leonardo Amato
* @version 9-25-2021
*/
@@ -28,72 +28,74 @@ public class ThreadMapUtil
public static final ConcurrentMap<String, short[]> heightAndDepthMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, long[]> singleDataToMergeMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, long[][]> verticalUpdate = new ConcurrentHashMap<>();
//________________________//
// used in BufferBuilder //
//________________________//
public static final ConcurrentMap<String, boolean[]> adjShadeDisabled = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, Map<Direction ,long[]>> adjDataMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, Map<Direction, long[]>> adjDataMap = new ConcurrentHashMap<>();
public static final ConcurrentMap<String, Box> boxMap = new ConcurrentHashMap<>();
/** returns the array NOT cleared every time
* @return*/
public static boolean[] getAdjShadeDisabledArray()
{
if (!adjShadeDisabled.containsKey(Thread.currentThread().getName())
|| (adjShadeDisabled.get(Thread.currentThread().getName()) == null))
|| (adjShadeDisabled.get(Thread.currentThread().getName()) == null))
{
adjShadeDisabled.put(Thread.currentThread().getName(), new boolean[Box.DIRECTIONS.length]);
}
Arrays.fill(adjShadeDisabled.get(Thread.currentThread().getName()), false);
return adjShadeDisabled.get(Thread.currentThread().getName());
}
/** returns the array NOT cleared every time */
public static Map<Direction ,long[]> getAdjDataArray(int verticalData)
public static Map<Direction, long[]> getAdjDataArray(int verticalData)
{
if (!adjDataMap.containsKey(Thread.currentThread().getName())
|| (adjDataMap.get(Thread.currentThread().getName()) == null)
|| (adjDataMap.get(Thread.currentThread().getName()).get(Direction.UP) == null)
|| (adjDataMap.get(Thread.currentThread().getName()).get(Direction.UP).length != verticalData))
|| (adjDataMap.get(Thread.currentThread().getName()) == null)
|| (adjDataMap.get(Thread.currentThread().getName()).get(Direction.UP) == null)
|| (adjDataMap.get(Thread.currentThread().getName()).get(Direction.UP).length != verticalData))
{
adjDataMap.put(Thread.currentThread().getName(), new HashMap());
for (Direction direction : Box.ADJ_DIRECTIONS)
adjDataMap.get(Thread.currentThread().getName()).put(direction, new long[verticalData]);
}else{
}
else
{
for (Direction direction : Box.ADJ_DIRECTIONS)
Arrays.fill(adjDataMap.get(Thread.currentThread().getName()).get(direction),DataPointUtil.EMPTY_DATA);
Arrays.fill(adjDataMap.get(Thread.currentThread().getName()).get(direction), DataPointUtil.EMPTY_DATA);
}
return adjDataMap.get(Thread.currentThread().getName());
}
public static Box getBox()
{
if (!boxMap.containsKey(Thread.currentThread().getName())
|| (boxMap.get(Thread.currentThread().getName()) == null))
|| (boxMap.get(Thread.currentThread().getName()) == null))
{
boxMap.put(Thread.currentThread().getName(), new Box());
}
boxMap.get(Thread.currentThread().getName()).reset();
return boxMap.get(Thread.currentThread().getName());
}
//________________________//
// used in DataPointUtil //
// mergeVerticalData //
//________________________//
//________________________//
// used in DataPointUtil //
// mergeSingleData //
//________________________//
/** returns the array NOT cleared every time */
public static long[] getSingleUpdateArray()
{