Start removing the old LOD objects

This commit is contained in:
James Seibel
2021-08-11 07:29:51 -05:00
parent 1095f63832
commit 412f1bead0
24 changed files with 171 additions and 151 deletions
@@ -44,6 +44,7 @@ import com.seibel.lod.objects.LodQuadTreeDimension;
import com.seibel.lod.objects.LodQuadTreeNode;
import com.seibel.lod.objects.RegionPos;
import com.seibel.lod.util.BiomeColorsUtils;
import com.seibel.lod.util.LodUtil;
import kaptainwutax.biomeutils.source.OverworldBiomeSource;
import kaptainwutax.mcutils.version.MCVersion;
@@ -154,8 +155,8 @@ public class QuadTreeImage extends JPanel
int centerX = node.center.getX();
int centerZ = node.center.getZ();
int width = node.width;
byte otherLevel = LodQuadTreeNode.BLOCK_LEVEL;
int otherWidth = LodQuadTreeNode.BLOCK_WIDTH;
byte otherLevel = LodUtil.BLOCK_DETAIL_LEVEL;
int otherWidth = LodUtil.BLOCK_WIDTH;
List<Integer> posXs = new ArrayList<>();
List<Integer> posZs = new ArrayList<>();
@@ -113,12 +113,12 @@ public class LodBufferBuilder
// this seemingly useless math is required,
// just using (int) playerX/Z doesn't work
int playerXChunkOffset = ((int) playerX / LodChunk.WIDTH) * LodChunk.WIDTH;
int playerZChunkOffset = ((int) playerZ / LodChunk.WIDTH) * LodChunk.WIDTH;
int playerXChunkOffset = ((int) playerX / LodUtil.CHUNK_WIDTH) * LodUtil.CHUNK_WIDTH;
int playerZChunkOffset = ((int) playerZ / LodUtil.CHUNK_WIDTH) * LodUtil.CHUNK_WIDTH;
// this is where we will start drawing squares
// (exactly half the total width)
int startX = (-LodChunk.WIDTH * (numbChunksWide / 2)) + playerXChunkOffset;
int startZ = (-LodChunk.WIDTH * (numbChunksWide / 2)) + playerZChunkOffset;
int startX = (-LodUtil.CHUNK_WIDTH * (numbChunksWide / 2)) + playerXChunkOffset;
int startZ = (-LodUtil.CHUNK_WIDTH * (numbChunksWide / 2)) + playerZChunkOffset;
Thread thread = new Thread(()->
@@ -132,7 +132,7 @@ public class LodBufferBuilder
// we can top it off from the reserve
ChunkPos[] chunksToGenReserve = new ChunkPos[maxChunkGenRequests];
int minChunkDist = Integer.MAX_VALUE;
ChunkPos playerChunkPos = new ChunkPos((int)playerX / LodChunk.WIDTH, (int)playerZ / LodChunk.WIDTH);
ChunkPos playerChunkPos = new ChunkPos((int)playerX / LodUtil.CHUNK_WIDTH, (int)playerZ / LodUtil.CHUNK_WIDTH);
// generate our new buildable buffers
@@ -147,8 +147,8 @@ public class LodBufferBuilder
// z axis
for (int j = 0; j < numbChunksWide; j++)
{
int chunkX = i + (startX / LodChunk.WIDTH);
int chunkZ = j + (startZ / LodChunk.WIDTH);
int chunkX = i + (startX / LodUtil.CHUNK_WIDTH);
int chunkZ = j + (startZ / LodUtil.CHUNK_WIDTH);
// skip any chunks that Minecraft is going to render
if(isCoordInCenterArea(i, j, (numbChunksWide / 2))
@@ -157,14 +157,14 @@ public class LodBufferBuilder
continue;
}
LodDetail detail = LodConfig.CLIENT.lodDetail.get();
LodDetail detail = LodConfig.CLIENT.maxDrawDetail.get();
// set where this square will be drawn in the world
double xOffset = (LodChunk.WIDTH * i) + // offset by the number of LOD blocks
double xOffset = (LodUtil.CHUNK_WIDTH * i) + // offset by the number of LOD blocks
startX + // offset so the center LOD block is centered underneath the player
8; //detail.offset; // truncation(?) correction
double yOffset = 0;
double zOffset = (LodChunk.WIDTH * j) + startZ + 8;//detail.offset;
double zOffset = (LodUtil.CHUNK_WIDTH * j) + startZ + 8;//detail.offset;
LodChunk lod = lodDim.getLodFromCoordinates(chunkX, chunkZ);
@@ -60,8 +60,8 @@ public class LodChunkBuilder
public int regionWidth = 5;
public static final int CHUNK_DATA_WIDTH = LodChunk.WIDTH;
public static final int CHUNK_SECTION_HEIGHT = LodChunk.WIDTH;
public static final int CHUNK_DATA_WIDTH = LodUtil.CHUNK_WIDTH;
public static final int CHUNK_SECTION_HEIGHT = LodUtil.CHUNK_WIDTH;
@@ -155,7 +155,7 @@ public class LodChunkBuilder
throw new IllegalArgumentException("generateLodFromChunk given a null chunk");
LodDetail detail = LodConfig.CLIENT.lodDetail.get();
LodDetail detail = LodConfig.CLIENT.maxGenerationDetail.get();
LodDataPoint[][] dataPoints = new LodDataPoint[detail.dataPointLengthCount][detail.dataPointLengthCount];
for(int i = 0; i < detail.dataPointLengthCount * detail.dataPointLengthCount; i++)
@@ -180,7 +180,7 @@ public class LodChunkBuilder
}
else
{
height = determineHeightPoint(chunk.getOrCreateHeightmapUnprimed(LodChunk.DEFAULT_HEIGHTMAP), startX, startZ, endX, endZ);
height = determineHeightPoint(chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP), startX, startZ, endX, endZ);
depth = 0;
}
@@ -129,12 +129,12 @@ public class LodNodeBufferBuilder
// this seemingly useless math is required,
// just using (int) playerX/Z doesn't work
int playerXChunkOffset = ((int) playerX / LodQuadTreeNode.CHUNK_WIDTH) * LodQuadTreeNode.CHUNK_WIDTH;
int playerZChunkOffset = ((int) playerZ / LodQuadTreeNode.CHUNK_WIDTH) * LodQuadTreeNode.CHUNK_WIDTH;
int playerXChunkOffset = ((int) playerX / LodUtil.CHUNK_WIDTH) * LodUtil.CHUNK_WIDTH;
int playerZChunkOffset = ((int) playerZ / LodUtil.CHUNK_WIDTH) * LodUtil.CHUNK_WIDTH;
// this is where we will start drawing squares
// (exactly half the total width)
int startX = (-LodQuadTreeNode.CHUNK_WIDTH * (numbChunksWide / 2)) + playerXChunkOffset;
int startZ = (-LodQuadTreeNode.CHUNK_WIDTH * (numbChunksWide / 2)) + playerZChunkOffset;
int startX = (-LodUtil.CHUNK_WIDTH * (numbChunksWide / 2)) + playerXChunkOffset;
int startZ = (-LodUtil.CHUNK_WIDTH * (numbChunksWide / 2)) + playerZChunkOffset;
Thread thread = new Thread(() ->
@@ -148,7 +148,7 @@ public class LodNodeBufferBuilder
// we can top it off from the reserve
ChunkPos[] chunksToGenReserve = new ChunkPos[maxChunkGenRequests];
int minChunkDist = Integer.MAX_VALUE;
ChunkPos playerChunkPos = new ChunkPos((int)playerX / LodQuadTreeNode.CHUNK_WIDTH, (int)playerZ / LodQuadTreeNode.CHUNK_WIDTH);
ChunkPos playerChunkPos = new ChunkPos((int)playerX / LodUtil.CHUNK_WIDTH, (int)playerZ / LodUtil.CHUNK_WIDTH);
// generate our new buildable buffers
@@ -160,8 +160,8 @@ public class LodNodeBufferBuilder
{
// z axis
for (int j = 0; j < numbChunksWide; j++) {
int chunkX = i + Math.floorDiv(startX, LodQuadTreeNode.CHUNK_WIDTH);
int chunkZ = j + Math.floorDiv(startZ, LodQuadTreeNode.CHUNK_WIDTH);
int chunkX = i + Math.floorDiv(startX, LodUtil.CHUNK_WIDTH);
int chunkZ = j + Math.floorDiv(startZ, LodUtil.CHUNK_WIDTH);
// skip any chunks that Minecraft is going to render
if (isCoordInCenterArea(i, j, (numbChunksWide / 2))
@@ -171,12 +171,12 @@ public class LodNodeBufferBuilder
// set where this square will be drawn in the world
double xOffset = (LodQuadTreeNode.CHUNK_WIDTH * i) + // offset by the number of LOD blocks
double xOffset = (LodUtil.CHUNK_WIDTH * i) + // offset by the number of LOD blocks
startX; // offset so the center LOD block is centered underneath the player
double yOffset = 0;
double zOffset = (LodQuadTreeNode.CHUNK_WIDTH * j) + startZ;
double zOffset = (LodUtil.CHUNK_WIDTH * j) + startZ;
LodQuadTreeNode lod = lodDim.getLodFromCoordinates(new ChunkPos(chunkX, chunkZ), LodQuadTreeNode.CHUNK_LEVEL);
LodQuadTreeNode lod = lodDim.getLodFromCoordinates(new ChunkPos(chunkX, chunkZ), LodUtil.CHUNK_DETAIL_LEVEL);
if (lod == null || lod.complexity == DistanceGenerationMode.NONE) {
// generate a new chunk if no chunk currently exists
@@ -25,7 +25,6 @@ import java.util.concurrent.Executors;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.objects.LodDataPoint;
import com.seibel.lod.objects.LodQuadTreeDimension;
import com.seibel.lod.objects.LodQuadTreeNode;
@@ -58,7 +57,7 @@ public class LodNodeBuilder
{
private ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor();
public static final int CHUNK_DATA_WIDTH = LodQuadTreeNode.CHUNK_WIDTH;
public static final int CHUNK_DATA_WIDTH = LodUtil.CHUNK_WIDTH;
public static final int CHUNK_SECTION_HEIGHT = CHUNK_DATA_WIDTH;
public static final Heightmap.Type DEFAULT_HEIGHTMAP = Heightmap.Type.WORLD_SURFACE_WG;
@@ -166,7 +165,7 @@ public class LodNodeBuilder
}
else
{
height = determineHeightPoint(chunk.getOrCreateHeightmapUnprimed(LodChunk.DEFAULT_HEIGHTMAP), startX,
height = determineHeightPoint(chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP), startX,
startZ, endX, endZ);
depth = 0;
}
@@ -54,7 +54,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
// Add this LOD to the BufferBuilder
// using the quality setting set by the config
LodDetail detail = LodConfig.CLIENT.lodDetail.get();
LodDetail detail = LodConfig.CLIENT.maxDrawDetail.get();
// returns null if the lod is empty at the given location
bbox = generateBoundingBox(
@@ -33,8 +33,8 @@ import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.handlers.LodConfig;
import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodRegion;
import com.seibel.lod.render.LodRenderer;
import com.seibel.lod.util.LodUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -181,7 +181,7 @@ public class LodChunkGenWorker implements IWorker
{
// only generate LodChunks if they can
// be added to the current LodDimension
if (lodDim.regionIsInRange(pos.x / LodRegion.SIZE, pos.z / LodRegion.SIZE))
if (lodDim.regionIsInRange(pos.x / LodUtil.REGION_WIDTH_IN_CHUNKS, pos.z / LodUtil.REGION_WIDTH_IN_CHUNKS))
{
// long startTime = System.currentTimeMillis();
@@ -256,10 +256,10 @@ public class LodChunkGenWorker implements IWorker
boolean inTheEnd = false;
// add fake heightmap data so our LODs aren't at height 0
Heightmap heightmap = new Heightmap(chunk, LodChunk.DEFAULT_HEIGHTMAP);
for(int x = 0; x < LodChunk.WIDTH && !inTheEnd; x++)
Heightmap heightmap = new Heightmap(chunk, LodUtil.DEFAULT_HEIGHTMAP);
for(int x = 0; x < LodUtil.CHUNK_WIDTH && !inTheEnd; x++)
{
for(int z = 0; z < LodChunk.WIDTH && !inTheEnd; z++)
for(int z = 0; z < LodUtil.CHUNK_WIDTH && !inTheEnd; z++)
{
if (simulateHeight)
{
@@ -320,7 +320,7 @@ public class LodChunkGenWorker implements IWorker
}// z
}// x
chunk.setHeightmap(LodChunk.DEFAULT_HEIGHTMAP, heightmap.getRawData());
chunk.setHeightmap(LodUtil.DEFAULT_HEIGHTMAP, heightmap.getRawData());
LodChunk lod;
@@ -400,9 +400,9 @@ public class LodChunkGenWorker implements IWorker
// get all the biomes in the chunk
HashSet<Biome> biomes = new HashSet<>();
for (int x = 0; x < LodChunk.WIDTH; x++)
for (int x = 0; x < LodUtil.CHUNK_WIDTH; x++)
{
for (int z = 0; z < LodChunk.WIDTH; z++)
for (int z = 0; z < LodUtil.CHUNK_WIDTH; z++)
{
Biome biome = chunk.getBiomes().getNoiseBiome(x >> 2, serverWorld.getSeaLevel() >> 2, z >> 2);
@@ -31,12 +31,11 @@ import com.seibel.lod.builders.LodNodeBufferBuilder;
import com.seibel.lod.builders.LodNodeBuilder;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.handlers.LodConfig;
import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.objects.LodQuadTreeDimension;
import com.seibel.lod.objects.LodQuadTreeNode;
import com.seibel.lod.objects.LodRegion;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.render.LodNodeRenderer;
import com.seibel.lod.util.LodUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -185,7 +184,7 @@ public class LodNodeGenWorker implements IWorker
{
// only generate LodChunks if they can
// be added to the current LodDimension
if (lodDim.regionIsInRange(pos.x / LodRegion.SIZE, pos.z / LodRegion.SIZE))
if (lodDim.regionIsInRange(pos.x / LodUtil.REGION_WIDTH_IN_CHUNKS, pos.z / LodUtil.REGION_WIDTH_IN_CHUNKS))
{
// long startTime = System.currentTimeMillis();
@@ -268,10 +267,10 @@ public class LodNodeGenWorker implements IWorker
boolean inTheEnd = false;
// add fake heightmap data so our LODs aren't at height 0
Heightmap heightmap = new Heightmap(chunk, LodChunk.DEFAULT_HEIGHTMAP);
for(int x = 0; x < LodChunk.WIDTH && !inTheEnd; x++)
Heightmap heightmap = new Heightmap(chunk, LodUtil.DEFAULT_HEIGHTMAP);
for(int x = 0; x < LodUtil.CHUNK_WIDTH && !inTheEnd; x++)
{
for(int z = 0; z < LodChunk.WIDTH && !inTheEnd; z++)
for(int z = 0; z < LodUtil.CHUNK_WIDTH && !inTheEnd; z++)
{
if (simulateHeight)
{
@@ -332,7 +331,7 @@ public class LodNodeGenWorker implements IWorker
}// z
}// x
chunk.setHeightmap(LodChunk.DEFAULT_HEIGHTMAP, heightmap.getRawData());
chunk.setHeightmap(LodUtil.DEFAULT_HEIGHTMAP, heightmap.getRawData());
List<LodQuadTreeNode> nodeList;
@@ -415,9 +414,9 @@ public class LodNodeGenWorker implements IWorker
// get all the biomes in the chunk
HashSet<Biome> biomes = new HashSet<>();
for (int x = 0; x < LodChunk.WIDTH; x++)
for (int x = 0; x < LodUtil.CHUNK_WIDTH; x++)
{
for (int z = 0; z < LodChunk.WIDTH; z++)
for (int z = 0; z < LodUtil.CHUNK_WIDTH; z++)
{
Biome biome = chunk.getBiomes().getNoiseBiome(x >> 2, serverWorld.getSeaLevel() >> 2, z >> 2);
@@ -23,7 +23,7 @@ import java.util.Random;
import java.util.function.Predicate;
import java.util.stream.Stream;
import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.util.LodUtil;
import net.minecraft.block.Block;
import net.minecraft.block.BlockState;
@@ -89,13 +89,13 @@ public class LodServerWorld implements ISeedReader {
public int getHeight(Type heightmapType, int x, int z)
{
// make sure the block position is set relative to the chunk
x = x % LodChunk.WIDTH;
x = x % LodUtil.CHUNK_WIDTH;
x = (x < 0) ? x + 16 : x;
z = z % LodChunk.WIDTH;
z = z % LodUtil.CHUNK_WIDTH;
z = (z < 0) ? z + 16 : z;
return chunk.getOrCreateHeightmapUnprimed(LodChunk.DEFAULT_HEIGHTMAP).getFirstAvailable(x, z);
return chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP).getFirstAvailable(x, z);
}
@Override
@@ -59,7 +59,9 @@ public class LodConfig
public ForgeConfigSpec.EnumValue<LodTemplate> lodTemplate;
public ForgeConfigSpec.EnumValue<LodDetail> lodDetail;
public ForgeConfigSpec.EnumValue<LodDetail> maxDrawDetail;
public ForgeConfigSpec.EnumValue<LodDetail> maxGenerationDetail;
public ForgeConfigSpec.EnumValue<DistanceGenerationMode> distanceGenerationMode;
@@ -78,6 +80,8 @@ public class LodConfig
public ForgeConfigSpec.DoubleValue saturationMultiplier;
Client(ForgeConfigSpec.Builder builder)
{
builder.comment(ModInfo.MODNAME + " configuration settings").push("client");
@@ -123,7 +127,8 @@ public class LodConfig
+ " " + " unless a neighboring chunk is at a significantly different height. \n")
.defineEnum("lodTemplate", LodTemplate.CUBIC);
lodDetail = builder
// TODO comment
maxDrawDetail = builder
.comment("\n\n"
+ " How detailed should the LODs be? \n"
+ " " + LodDetail.SINGLE.toString() + ": render 1 LOD for each Chunk. \n"
@@ -132,6 +137,17 @@ public class LodConfig
+ " " + LodDetail.HALF.toString() + ": render 64 LODs for each Chunk. \n")
.defineEnum("lodGeometryQuality", LodDetail.DOUBLE);
// TODO comment
maxGenerationDetail = builder
.comment("\n\n"
+ " How detailed should the LODs be? \n"
+ " " + LodDetail.SINGLE.toString() + ": render 1 LOD for each Chunk. \n"
+ " " + LodDetail.DOUBLE.toString() + ": render 4 LODs for each Chunk. \n"
+ " " + LodDetail.QUAD.toString() + ": render 16 LODs for each Chunk. \n"
+ " " + LodDetail.HALF.toString() + ": render 64 LODs for each Chunk. \n")
.defineEnum("lodGeometryQuality", LodDetail.DOUBLE);
lodChunkRadiusMultiplier = builder
.comment("\n\n"
+ " This is multiplied by the default view distance \n"
@@ -41,10 +41,6 @@ import com.seibel.lod.proxy.ClientProxy;
*/
public class LodDimensionFileHandler
{
/** This is what separates each piece of data */
public static final char DATA_DELIMITER = ',';
private LodDimension loadedDimension = null;
public long regionLastWriteTime[][];
@@ -100,7 +96,7 @@ public class LodDimensionFileHandler
public LodRegion loadRegionFromFile(int regionX, int regionZ)
{
String fileName = getFileNameAndPathForRegion(regionX, regionZ, LodConfig.CLIENT.lodDetail.get());
String fileName = getFileNameAndPathForRegion(regionX, regionZ, LodConfig.CLIENT.maxDrawDetail.get());
File f = new File(fileName);
@@ -175,7 +171,7 @@ public class LodDimensionFileHandler
try
{
// convert each line into an LOD object and add it to the region
LodChunk lod = new LodChunk(s, LodConfig.CLIENT.lodDetail.get());
LodChunk lod = new LodChunk(s, LodConfig.CLIENT.maxDrawDetail.get());
region.addLod(lod);
}
@@ -251,7 +247,7 @@ public class LodDimensionFileHandler
int x = region.x;
int z = region.z;
File f = new File(getFileNameAndPathForRegion(x, z, LodConfig.CLIENT.lodDetail.get()));
File f = new File(getFileNameAndPathForRegion(x, z, LodConfig.CLIENT.maxDrawDetail.get()));
try
{
@@ -34,8 +34,6 @@ import com.seibel.lod.objects.LodQuadTreeNode;
import com.seibel.lod.objects.RegionPos;
import com.seibel.lod.proxy.ClientProxy;
import net.minecraft.util.math.ChunkPos;
/**
* This object handles creating LodRegions
* from files and saving LodRegion objects
@@ -20,10 +20,9 @@ package com.seibel.lod.objects;
import java.awt.Color;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.handlers.LodDimensionFileHandler;
import com.seibel.lod.handlers.LodQuadTreeDimensionFileHandler;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.gen.Heightmap;
/**
* This object contains position
@@ -35,10 +34,7 @@ import net.minecraft.world.gen.Heightmap;
public class LodChunk
{
/** This is what separates each piece of data in the toData method */
private static final char DATA_DELIMITER = LodDimensionFileHandler.DATA_DELIMITER;
/** Width of a Minecraft Chunk */
public static final int WIDTH = 16;
private static final char DATA_DELIMITER = LodQuadTreeDimensionFileHandler.DATA_DELIMITER;
/** alpha used when drawing chunks in debug mode */
private static final int DEBUG_ALPHA = 255; // 0 - 255
@@ -46,10 +42,6 @@ public class LodChunk
private static final Color DEBUG_WHITE = new Color(255, 255, 255, DEBUG_ALPHA);
private static final Color INVISIBLE = new Color(0,0,0,0);
/** If we ever have to use a heightmap for any reason, use this one. */
public static final Heightmap.Type DEFAULT_HEIGHTMAP = Heightmap.Type.WORLD_SURFACE_WG;
public LodDetail detail = LodDetail.SINGLE;
/** If this is set to true then toData will return
@@ -20,7 +20,7 @@ package com.seibel.lod.objects;
import java.awt.Color;
import java.util.Objects;
import com.seibel.lod.handlers.LodDimensionFileHandler;
import com.seibel.lod.handlers.LodQuadTreeDimensionFileHandler;
import com.seibel.lod.util.LodUtil;
/**
@@ -33,7 +33,7 @@ import com.seibel.lod.util.LodUtil;
public class LodDataPoint
{
/** This is what separates each piece of data in the toData method */
private static final char DATA_DELIMITER = LodDimensionFileHandler.DATA_DELIMITER;
private static final char DATA_DELIMITER = LodQuadTreeDimensionFileHandler.DATA_DELIMITER;
/** this is how many pieces of data are exported when toData is called */
public static final int NUMBER_OF_DELIMITERS = 5;
@@ -23,6 +23,7 @@ import java.util.List;
import java.util.Set;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.util.LodUtil;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
@@ -113,7 +114,7 @@ public class LodQuadTree
//maybe the use of useLevelCoordinate could be changed. I could use a builder to do all this work.
public LodQuadTree(RegionPos regionPos)
{
this(null, new LodQuadTreeNode(LodQuadTreeNode.REGION_LEVEL, regionPos.x, regionPos.z));
this(null, new LodQuadTreeNode(LodUtil.REGION_DETAIL_LEVEL, regionPos.x, regionPos.z));
}
/**
@@ -138,7 +139,7 @@ public class LodQuadTree
*/
public LodQuadTree(List<LodQuadTreeNode> dataList, int regionX, int regionZ)
{
this(null, new LodQuadTreeNode(LodQuadTreeNode.REGION_LEVEL, regionX, regionZ));
this(null, new LodQuadTreeNode(LodUtil.REGION_DETAIL_LEVEL, regionX, regionZ));
setNodesAtLowerLevel(dataList);
}
@@ -224,7 +225,7 @@ public class LodQuadTree
*/
public LodQuadTreeNode getNodeAtChunkPos(ChunkPos chunkPos)
{
return getNodeAtPos(chunkPos.x, chunkPos.z, LodQuadTreeNode.CHUNK_LEVEL);
return getNodeAtPos(chunkPos.x, chunkPos.z, LodUtil.CHUNK_DETAIL_LEVEL);
}
/**
@@ -233,8 +234,8 @@ public class LodQuadTree
*/
public LodQuadTreeNode getNodeAtPos(int posX, int posZ, int detailLevel)
{
if (detailLevel > LodQuadTreeNode.REGION_LEVEL)
throw new IllegalArgumentException("getNodeAtChunkPos given a level of \"" + detailLevel + "\" when \"" + LodQuadTreeNode.REGION_LEVEL + "\" is the max.");
if (detailLevel > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getNodeAtChunkPos given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
byte currentDetailLevel = lodNode.detailLevel;
@@ -269,8 +270,8 @@ public class LodQuadTree
*/
public LodQuadTree getLevelAtPos(int posX, int posZ, int detailLevel)
{
if (detailLevel > LodQuadTreeNode.REGION_LEVEL)
throw new IllegalArgumentException("getNodeAtChunkPos given a level of \"" + detailLevel + "\" when \"" + LodQuadTreeNode.REGION_LEVEL + "\" is the max.");
if (detailLevel > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getNodeAtChunkPos given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
byte currentDetailLevel = lodNode.detailLevel;
@@ -365,7 +366,7 @@ public class LodQuadTree
lodNode.combineData(dataList);
// update sub regions if requested
if (lodNode.detailLevel < LodQuadTreeNode.REGION_LEVEL && recursiveUpdate)
if (lodNode.detailLevel < LodUtil.REGION_DETAIL_LEVEL && recursiveUpdate)
{
this.parent.updateRegion(recursiveUpdate);
}
@@ -369,7 +369,7 @@ public class LodQuadTreeDimension
*/
public LodQuadTreeNode getLodFromCoordinates(ChunkPos chunkPos)
{
return getLodFromCoordinates(chunkPos, LodQuadTreeNode.CHUNK_LEVEL);
return getLodFromCoordinates(chunkPos, LodUtil.CHUNK_DETAIL_LEVEL);
}
/**
@@ -381,10 +381,10 @@ public class LodQuadTreeDimension
*/
public LodQuadTreeNode getLodFromCoordinates(ChunkPos chunkPos, int detailLevel)
{
if (detailLevel > LodQuadTreeNode.REGION_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodQuadTreeNode.REGION_LEVEL + "\" is the max.");
if (detailLevel > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
LodQuadTree region = getRegion(LodUtil.convertGenericPosToRegionPos(chunkPos.x, chunkPos.z, LodQuadTreeNode.CHUNK_LEVEL));
LodQuadTree region = getRegion(LodUtil.convertGenericPosToRegionPos(chunkPos.x, chunkPos.z, LodUtil.CHUNK_DETAIL_LEVEL));
if(region == null)
{
@@ -403,8 +403,8 @@ public class LodQuadTreeDimension
*/
public LodQuadTreeNode getLodFromCoordinates(int posX, int posZ, int detailLevel)
{
if (detailLevel > LodQuadTreeNode.REGION_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodQuadTreeNode.REGION_LEVEL + "\" is the max.");
if (detailLevel > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
LodQuadTree region = getRegion(LodUtil.convertGenericPosToRegionPos(posX, posZ, detailLevel));
@@ -425,8 +425,8 @@ public class LodQuadTreeDimension
*/
public LodQuadTree getLevelFromPos(int posX, int posZ, int detailLevel)
{
if (detailLevel > LodQuadTreeNode.REGION_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodQuadTreeNode.REGION_LEVEL + "\" is the max.");
if (detailLevel > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
LodQuadTree region = getRegion(LodUtil.convertGenericPosToRegionPos(posX, posZ, detailLevel));
@@ -443,8 +443,8 @@ public class LodQuadTreeDimension
*/
public boolean hasThisPositionBeenGenerated(ChunkPos chunkPos, int level)
{
if (level > LodQuadTreeNode.REGION_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + level + "\" when \"" + LodQuadTreeNode.REGION_LEVEL + "\" is the max.");
if (level > LodUtil.REGION_DETAIL_LEVEL)
throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + level + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
return getLodFromCoordinates(chunkPos, level).detailLevel == level;
}
@@ -61,25 +61,12 @@ public class LodQuadTreeNode
public DistanceGenerationMode complexity;
/** Indicates how complicated this node is. <br>
* Goes from 0 to 9, 0 being the deepest (block size) and 9 being the highest (region size) */
* Goes from 0 to 9; 0 being the deepest (block size) and 9 being the highest (region size) */
public final byte detailLevel;
/** 512 blocks wide */
public static final byte REGION_LEVEL = 9;
/** 16 blocks wide */
public static final byte CHUNK_LEVEL = 4;
/** 1 block wide */
public static final byte BLOCK_LEVEL = 0;
/** Indicates the width in blocks of this node. <br>
* Goes from 1 to 512 */
public final short width;
/** detail level 9 */
public static final short REGION_WIDTH = 512;
/** detail level 4 */
public static final short CHUNK_WIDTH = 16;
/** detail level 0 */
public static final short BLOCK_WIDTH = 1;
// these 4 value indicate the corner of the LOD block
// they can be named SW, SE, NW, NE as the cardinal direction.
@@ -17,6 +17,8 @@
*/
package com.seibel.lod.objects;
import com.seibel.lod.util.LodUtil;
/**
* A LodRegion is a 32x32
* 2D array of LodChunk objects.
@@ -28,9 +30,6 @@ package com.seibel.lod.objects;
*/
public class LodRegion
{
/** number of chunks wide */
public static final int SIZE = 32;
/** X coordinate of this region */
public final int x;
/** Z coordinate of this region */
@@ -44,7 +43,7 @@ public class LodRegion
x = regionX;
z = regionZ;
chunks = new LodChunk[SIZE][SIZE];
chunks = new LodChunk[LodUtil.REGION_WIDTH_IN_CHUNKS][LodUtil.REGION_WIDTH_IN_CHUNKS];
}
@@ -59,8 +58,8 @@ public class LodRegion
// the region will negative first, therefore we don't have to
// store the LOD chunks at negative indexes since we search
// LOD the region first
int xIndex = Math.abs(lod.x % SIZE);
int zIndex = Math.abs(lod.z % SIZE);
int xIndex = Math.abs(lod.x % LodUtil.REGION_WIDTH_IN_CHUNKS);
int zIndex = Math.abs(lod.z % LodUtil.REGION_WIDTH_IN_CHUNKS);
chunks[xIndex][zIndex] = lod;
}
@@ -75,8 +74,8 @@ public class LodRegion
public LodChunk getLod(int chunkX, int chunkZ)
{
// since we add LOD's with ABS, we get them the same way
int arrayX = Math.abs(chunkX % SIZE);
int arrayZ = Math.abs(chunkZ % SIZE);
int arrayX = Math.abs(chunkX % LodUtil.REGION_WIDTH_IN_CHUNKS);
int arrayZ = Math.abs(chunkZ % LodUtil.REGION_WIDTH_IN_CHUNKS);
return chunks[arrayX][arrayZ];
}
@@ -17,6 +17,8 @@
*/
package com.seibel.lod.objects;
import com.seibel.lod.util.LodUtil;
import net.minecraft.util.math.ChunkPos;
/**
@@ -51,8 +53,8 @@ public class RegionPos
public RegionPos(ChunkPos pos)
{
RegionPos rPos = new RegionPos();
x = pos.x / LodQuadTreeNode.REGION_WIDTH;
z = pos.z / LodQuadTreeNode.REGION_WIDTH;
x = pos.x / LodUtil.REGION_WIDTH;
z = pos.z / LodUtil.REGION_WIDTH;
// prevent issues if X/Z is negative and less than 16
if (pos.x < 0)
@@ -30,10 +30,8 @@ import com.seibel.lod.enums.FogDrawOverride;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.enums.ShadingMode;
import com.seibel.lod.handlers.LodConfig;
import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.objects.LodQuadTreeDimension;
import com.seibel.lod.objects.LodQuadTreeWorld;
import com.seibel.lod.objects.LodRegion;
import com.seibel.lod.objects.RegionPos;
import com.seibel.lod.render.LodNodeRenderer;
import com.seibel.lod.util.LodUtil;
@@ -96,7 +94,7 @@ public class ClientProxy
// update each regions' width to match the new render distance
int newWidth = Math.max(4,
// TODO is this logic good?
(mc.options.renderDistance * LodChunk.WIDTH * 2 * LodConfig.CLIENT.lodChunkRadiusMultiplier.get()) / LodRegion.SIZE
(mc.options.renderDistance * LodUtil.CHUNK_WIDTH * 2 * LodConfig.CLIENT.lodChunkRadiusMultiplier.get()) / LodUtil.REGION_WIDTH_IN_CHUNKS
);
if (lodNodeBuilder.regionWidth != newWidth)
{
@@ -117,8 +115,8 @@ public class ClientProxy
double playerX = mc.player.getX();
double playerZ = mc.player.getZ();
int xOffset = ((int)playerX / (LodChunk.WIDTH * LodRegion.SIZE)) - lodDim.getCenterX();
int zOffset = ((int)playerZ / (LodChunk.WIDTH * LodRegion.SIZE)) - lodDim.getCenterZ();
int xOffset = ((int)playerX / (LodUtil.CHUNK_WIDTH * LodUtil.REGION_WIDTH_IN_CHUNKS)) - lodDim.getCenterX();
int zOffset = ((int)playerZ / (LodUtil.CHUNK_WIDTH * LodUtil.REGION_WIDTH_IN_CHUNKS)) - lodDim.getCenterZ();
if (xOffset != 0 || zOffset != 0)
{
@@ -160,7 +158,9 @@ public class ClientProxy
// LodConfig.CLIENT.drawLODs.set(true);
// LodConfig.CLIENT.debugMode.set(false);
LodConfig.CLIENT.lodDetail.set(LodDetail.QUAD);
LodConfig.CLIENT.maxDrawDetail.set(LodDetail.QUAD);
LodConfig.CLIENT.maxGenerationDetail.set(LodDetail.QUAD);
LodConfig.CLIENT.lodChunkRadiusMultiplier.set(12);
LodConfig.CLIENT.fogDistance.set(FogDistance.FAR);
LodConfig.CLIENT.fogDrawOverride.set(FogDrawOverride.ALWAYS_DRAW_FOG_FANCY);
@@ -40,6 +40,7 @@ import com.seibel.lod.objects.LodQuadTreeNode;
import com.seibel.lod.objects.NearFarBuffer;
import com.seibel.lod.objects.NearFarFogSettings;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.util.LodUtil;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
@@ -193,16 +194,16 @@ public class LodNodeRenderer
ClientPlayerEntity player = mc.player;
// should LODs be regenerated?
if ((int)player.getX() / LodQuadTreeNode.CHUNK_WIDTH != prevChunkX ||
(int)player.getZ() / LodQuadTreeNode.CHUNK_WIDTH != prevChunkZ ||
if ((int)player.getX() / LodUtil.CHUNK_WIDTH != prevChunkX ||
(int)player.getZ() / LodUtil.CHUNK_WIDTH != prevChunkZ ||
previousChunkRenderDistance != mc.options.renderDistance ||
prevFogDistance != LodConfig.CLIENT.fogDistance.get())
{
// yes
regen = true;
prevChunkX = (int)player.getX() / LodQuadTreeNode.CHUNK_WIDTH;
prevChunkZ = (int)player.getZ() / LodQuadTreeNode.CHUNK_WIDTH;
prevChunkX = (int)player.getX() / LodUtil.CHUNK_WIDTH;
prevChunkZ = (int)player.getZ() / LodUtil.CHUNK_WIDTH;
prevFogDistance = LodConfig.CLIENT.fogDistance.get();
}
else
@@ -222,11 +223,11 @@ public class LodNodeRenderer
// determine how far the game's render distance is currently set
int renderDistWidth = mc.options.renderDistance;
farPlaneDistance = renderDistWidth * LodQuadTreeNode.CHUNK_WIDTH;
farPlaneDistance = renderDistWidth * LodUtil.CHUNK_WIDTH;
// set how big the LODs will be and how far they will go
int totalLength = (int) farPlaneDistance * LodConfig.CLIENT.lodChunkRadiusMultiplier.get() * 2;
int numbChunksWide = (totalLength / LodQuadTreeNode.CHUNK_WIDTH);
int numbChunksWide = (totalLength / LodUtil.CHUNK_WIDTH);
// determine which LODs should not be rendered close to the player
HashSet<ChunkPos> chunkPosToSkip = getNearbyLodChunkPosToSkip(lodDim, player.blockPosition());
@@ -624,7 +625,7 @@ public class LodNodeRenderer
// to fit.
if (bufferMemory > MAX_ALOCATEABLE_DIRECT_MEMORY)
{
int maxRadiusMultiplier = RenderUtil.getMaxRadiusMultiplierWithAvaliableMemory(LodConfig.CLIENT.lodTemplate.get(), LodQuadTreeNode.CHUNK_LEVEL);
int maxRadiusMultiplier = RenderUtil.getMaxRadiusMultiplierWithAvaliableMemory(LodConfig.CLIENT.lodTemplate.get(), LodUtil.CHUNK_DETAIL_LEVEL);
ClientProxy.LOGGER.warn("The lodChunkRadiusMultiplier was set too high "
+ "and had to be lowered to fit memory constraints "
@@ -37,10 +37,10 @@ import com.seibel.lod.handlers.LodConfig;
import com.seibel.lod.handlers.ReflectionHandler;
import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodQuadTreeNode;
import com.seibel.lod.objects.NearFarBuffer;
import com.seibel.lod.objects.NearFarFogSettings;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.util.LodUtil;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.player.ClientPlayerEntity;
@@ -194,16 +194,16 @@ public class LodRenderer
ClientPlayerEntity player = mc.player;
// should LODs be regenerated?
if ((int)player.getX() / LodChunk.WIDTH != prevChunkX ||
(int)player.getZ() / LodChunk.WIDTH != prevChunkZ ||
if ((int)player.getX() / LodUtil.CHUNK_WIDTH != prevChunkX ||
(int)player.getZ() / LodUtil.CHUNK_WIDTH != prevChunkZ ||
previousChunkRenderDistance != mc.options.renderDistance ||
prevFogDistance != LodConfig.CLIENT.fogDistance.get())
{
// yes
regen = true;
prevChunkX = (int)player.getX() / LodChunk.WIDTH;
prevChunkZ = (int)player.getZ() / LodChunk.WIDTH;
prevChunkX = (int)player.getX() / LodUtil.CHUNK_WIDTH;
prevChunkZ = (int)player.getZ() / LodUtil.CHUNK_WIDTH;
prevFogDistance = LodConfig.CLIENT.fogDistance.get();
}
else
@@ -223,11 +223,11 @@ public class LodRenderer
// determine how far the game's render distance is currently set
int renderDistWidth = mc.options.renderDistance;
farPlaneDistance = renderDistWidth * LodChunk.WIDTH;
farPlaneDistance = renderDistWidth * LodUtil.CHUNK_WIDTH;
// set how big the LODs will be and how far they will go
int totalLength = (int) farPlaneDistance * LodConfig.CLIENT.lodChunkRadiusMultiplier.get() * 2;
int numbChunksWide = (totalLength / LodChunk.WIDTH);
int numbChunksWide = (totalLength / LodUtil.CHUNK_WIDTH);
// determine which LODs should not be rendered close to the player
HashSet<ChunkPos> chunkPosToSkip = getNearbyLodChunkPosToSkip(lodDim, player.blockPosition());
@@ -623,7 +623,7 @@ public class LodRenderer
// to fit.
if (bufferMemory > MAX_ALOCATEABLE_DIRECT_MEMORY)
{
int maxRadiusMultiplier = RenderUtil.getMaxRadiusMultiplierWithAvaliableMemory(LodConfig.CLIENT.lodTemplate.get(), LodQuadTreeNode.CHUNK_LEVEL);
int maxRadiusMultiplier = RenderUtil.getMaxRadiusMultiplierWithAvaliableMemory(LodConfig.CLIENT.lodTemplate.get(), LodUtil.CHUNK_DETAIL_LEVEL);
ClientProxy.LOGGER.warn("The lodChunkRadiusMultiplier was set too high "
+ "and had to be lowered to fit memory constraints "
@@ -19,7 +19,7 @@ package com.seibel.lod.render;
import com.seibel.lod.enums.LodTemplate;
import com.seibel.lod.handlers.LodConfig;
import com.seibel.lod.objects.LodQuadTreeNode;
import com.seibel.lod.util.LodUtil;
import net.minecraft.client.Minecraft;
import net.minecraft.util.math.ChunkPos;
@@ -94,7 +94,7 @@ public class RenderUtil
// calculate the max amount of buffer memory needed (in bytes)
return numbChunksWide * numbChunksWide *
LodConfig.CLIENT.lodTemplate.get().
getBufferMemoryForSingleLod(LodQuadTreeNode.CHUNK_LEVEL);
getBufferMemoryForSingleLod(LodUtil.CHUNK_DETAIL_LEVEL);
}
/**
+41 -12
View File
@@ -20,7 +20,6 @@ package com.seibel.lod.util;
import java.awt.Color;
import java.io.File;
import com.seibel.lod.objects.LodQuadTreeNode;
import com.seibel.lod.objects.RegionPos;
import net.minecraft.client.Minecraft;
@@ -30,6 +29,7 @@ import net.minecraft.world.DimensionType;
import net.minecraft.world.IWorld;
import net.minecraft.world.chunk.ChunkSection;
import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.gen.Heightmap;
import net.minecraft.world.server.ServerChunkProvider;
import net.minecraft.world.server.ServerWorld;
@@ -57,6 +57,33 @@ public class LodUtil
public static final Color DEBUG_DETAIL_LEVEL_COLORS[] = new Color[] { Color.RED, Color.ORANGE, Color.YELLOW, Color.GREEN, Color.BLUE, Color.MAGENTA, Color.pink};
/** 512 blocks wide */
public static final byte REGION_DETAIL_LEVEL = 9;
/** 16 blocks wide */
public static final byte CHUNK_DETAIL_LEVEL = 4;
/** 1 block wide */
public static final byte BLOCK_DETAIL_LEVEL = 0;
/** detail level 9 */
public static final short REGION_WIDTH = 512;
/** detail level 4 */
public static final short CHUNK_WIDTH = 16;
/** detail level 0 */
public static final short BLOCK_WIDTH = 1;
/** number of chunks wide */
public static final int REGION_WIDTH_IN_CHUNKS = 32;
/** If we ever have to use a heightmap for any reason, use this one. */
public static final Heightmap.Type DEFAULT_HEIGHTMAP = Heightmap.Type.WORLD_SURFACE_WG;
/**
* Gets the first valid ServerWorld.
*
@@ -71,7 +98,7 @@ public class LodUtil
for (ServerWorld world : worlds)
return world;
return null;
}
@@ -97,7 +124,7 @@ public class LodUtil
break;
}
}
return returnWorld;
}
@@ -106,19 +133,19 @@ public class LodUtil
*/
public static RegionPos convertGenericPosToRegionPos(int x, int z, int detailLevel)
{
int relativePosX = Math.floorDiv(x, (int) Math.pow(2, LodQuadTreeNode.REGION_LEVEL - detailLevel));
int relativePosZ = Math.floorDiv(z, (int) Math.pow(2, LodQuadTreeNode.REGION_LEVEL - detailLevel));
int relativePosX = Math.floorDiv(x, (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel));
int relativePosZ = Math.floorDiv(z, (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel));
return new RegionPos(relativePosX, relativePosZ);
}
/**
* Convert a 2D absolute position into a quad tree relative position.
*/
public static int convertLevelPos(int pos, int currectDetailLevel, int targetDetailLevel)
{
int newPos = Math.floorDiv(pos, (int) Math.pow(2, targetDetailLevel - currectDetailLevel));
return newPos;
}
/**
@@ -164,8 +191,8 @@ public class LodUtil
{
ServerData server = mc.getCurrentServer();
return server.name + ", IP " +
server.ip + ", GameVersion " +
server.version.getString();
server.ip + ", GameVersion " +
server.version.getString();
}
}
@@ -202,9 +229,9 @@ public class LodUtil
{
ServerData server = mc.getCurrentServer();
return server.name + ", IP " +
server.ip + ", GameVersion " +
server.version.getString() + File.separatorChar
+ "dim_" + world.dimensionType().effectsLocation().getPath() + File.separatorChar;
server.ip + ", GameVersion " +
server.version.getString() + File.separatorChar
+ "dim_" + world.dimensionType().effectsLocation().getPath() + File.separatorChar;
}
}
@@ -259,4 +286,6 @@ public class LodUtil
{
return Math.min(max, Math.max(value, min));
}
}