Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5

This commit is contained in:
James Seibel
2021-08-22 07:40:09 -05:00
12 changed files with 310 additions and 1024 deletions
@@ -0,0 +1,28 @@
package com.seibel.lod.builders;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.objects.LevelPos;
import com.seibel.lod.util.LodUtil;
import net.minecraft.util.math.ChunkPos;
/**
* @author Leonardo Amato
* @version 22-08-2021
*/
public class GenerationRequest
{
public final LevelPos levelPos;
public final DistanceGenerationMode generationMode;
public GenerationRequest(LevelPos levelPos, DistanceGenerationMode generationMode)
{
this.levelPos = levelPos;
this.generationMode = generationMode;
}
public ChunkPos getChunkPos()
{
LevelPos chunkLevelPos = levelPos.convert(LodUtil.CHUNK_DETAIL_LEVEL);
return new ChunkPos(chunkLevelPos.posX, chunkLevelPos.posZ);
}
}
@@ -26,6 +26,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
import com.seibel.lod.util.DetailUtil;
import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL11;
import com.seibel.lod.builders.worldGeneration.LodNodeGenWorker; import com.seibel.lod.builders.worldGeneration.LodNodeGenWorker;
@@ -177,41 +178,17 @@ public class LodBufferBuilder
// we can top it off from the reserve // we can top it off from the reserve
ArrayList<ChunkPos> chunksToGenReserve = new ArrayList<>(maxChunkGenRequests); ArrayList<ChunkPos> chunksToGenReserve = new ArrayList<>(maxChunkGenRequests);
/*
DistanceGenerationMode[] distancesGenerators = {DistanceGenerationMode.FEATURES,
DistanceGenerationMode.FEATURES,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.BIOME_ONLY,
DistanceGenerationMode.BIOME_ONLY,
DistanceGenerationMode.BIOME_ONLY,
DistanceGenerationMode.BIOME_ONLY,
DistanceGenerationMode.BIOME_ONLY}
*/
DistanceGenerationMode[] distancesGenerators = {
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE};
int[] distancesLinear = {0, 200, 400, 600, 800, 1000, 1500, 2000, 3000, 4000, 8000};
int[] distancesExponential = {0, 100, 200, 400, 800, 1600, 3200, 3200, 3200, 3200, 8000};
startBuffers(); startBuffers();
// used when determining which chunks are closer when queuing distance // used when determining which chunks are closer when queuing distance
// generation // generation
int minChunkDist = Integer.MAX_VALUE; int minChunkDist = Integer.MAX_VALUE;
int width; int width;
// =====================//
// RENDERING PART //
// =====================//
List<LevelPos> posListToRender = new ArrayList<>(); List<LevelPos> posListToRender = new ArrayList<>();
LodDataPoint lodData; LodDataPoint lodData;
for (int xRegion = 0; xRegion < lodDim.regions.length; xRegion++) for (int xRegion = 0; xRegion < lodDim.regions.length; xRegion++)
@@ -231,34 +208,38 @@ public class LodBufferBuilder
/**TODO make this automatic and config dependent*/ /**TODO make this automatic and config dependent*/
for (byte detail = LodUtil.BLOCK_DETAIL_LEVEL; detail <= LodUtil.REGION_DETAIL_LEVEL; detail++) for (byte detail = LodUtil.BLOCK_DETAIL_LEVEL; detail <= LodUtil.REGION_DETAIL_LEVEL; detail++)
{ {
posListToRender.addAll(lodDim.getDataToRender(regionPos, playerBlockPosRounded.getX(), playerBlockPosRounded.getZ(), distancesLinear[detail], distancesLinear[detail + 1], detail)); posListToRender.addAll(lodDim.getDataToRender(
regionPos,
playerBlockPosRounded.getX(),
playerBlockPosRounded.getZ(),
DetailUtil.getDistanceRendering(detail),
DetailUtil.getDistanceRendering(detail + 1),
detail));
} }
for (LevelPos pos : posListToRender) for (LevelPos pos : posListToRender)
{ {
LevelPos chunkPos = pos.convert((byte) 2); LevelPos chunkPos = pos.convert(LodUtil.CHUNK_DETAIL_LEVEL);
int chunkX = chunkPos.posX + startChunkPos.x;
int chunkZ = chunkPos.posZ + startChunkPos.z;
// skip any chunks that Minecraft is going to render // skip any chunks that Minecraft is going to render
if (isCoordInCenterArea(chunkPos.posX, chunkPos.posZ, (numbChunksWide / 2)) || renderer.vanillaRenderedChunks.contains(new ChunkPos(chunkX, chunkZ)))
if (renderer.vanillaRenderedChunks.contains(new ChunkPos( chunkPos.posX, chunkPos.posZ)))
{ {
continue; continue;
} }
if (lodDim.doesDataExist(pos)) if (lodDim.doesDataExist(pos))
{ {
try try
{ {
width = (int) Math.pow(2, pos.detailLevel); width = (int) Math.pow(2, pos.detailLevel);
lodData = lodDim.getData(pos); lodData = lodDim.getData(pos);
LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, lodDim, lodData, LodConfig.CLIENT.lodTemplate.get().template.addLodToBuffer(currentBuffer, lodDim, lodData,
pos.posX * width, 0, pos.posZ * width, renderer.debugging, pos.detailLevel); pos.posX * width, 0, pos.posZ * width, renderer.debugging, pos.detailLevel);
} } catch (ArrayIndexOutOfBoundsException e)
catch (ArrayIndexOutOfBoundsException e) {
{ ClientProxy.LOGGER.warn("LodBufferBuilder ran into trouble and had to start over.");
ClientProxy.LOGGER.warn("LodBufferBuilder ran into trouble and had to start over."); closeBuffers();
closeBuffers(); return;
return; }
}
} }
} }
@@ -267,10 +248,15 @@ public class LodBufferBuilder
} }
} }
/**TODO make this automatic and config dependent*/
// =====================//
// GENERATION PART //
// =====================//
List<LevelPos> posListToGenerate = new ArrayList<>(); List<LevelPos> posListToGenerate = new ArrayList<>();
/**TODO this order can be inverted*/ /**TODO can give a totally different generation*/
/* /*
for (byte detail = LodUtil.BLOCK_DETAIL_LEVEL; detail <= LodUtil.REGION_DETAIL_LEVEL; detail++) for (byte detail = LodUtil.BLOCK_DETAIL_LEVEL; detail <= LodUtil.REGION_DETAIL_LEVEL; detail++)
{ {
@@ -289,137 +275,141 @@ public class LodBufferBuilder
System.out.println("HERE"); System.out.println("HERE");
} }
} }
*/ */
int requesting = maxChunkGenRequests; int requesting = maxChunkGenRequests;
//we firstly make sure that the world is filled with half region wide block
for (byte detailGen = LodUtil.BLOCK_DETAIL_LEVEL; detailGen <= LodUtil.REGION_DETAIL_LEVEL; detailGen++) for (byte detailGen = LodUtil.BLOCK_DETAIL_LEVEL; detailGen <= LodUtil.REGION_DETAIL_LEVEL; detailGen++)
{ {
if (requesting == 0) break; if (requesting == 0) break;
posListToGenerate.addAll(lodDim.getDataToGenerate( posListToGenerate.addAll(lodDim.getDataToGenerate(
playerBlockPosRounded.getX(), playerBlockPosRounded.getX(),
playerBlockPosRounded.getZ(), playerBlockPosRounded.getZ(),
(int) (distancesLinear[detailGen] * 1.5), DetailUtil.getDistanceGeneration(detailGen),
(int) (distancesLinear[detailGen + 1] * 1.5), DetailUtil.getDistanceGeneration(detailGen + 1),
(byte) distancesGenerators[detailGen].complexity, DetailUtil.getDistanceGenerationMode(detailGen).complexity,
(byte) 8, (byte) 7,
requesting)); requesting));
requesting = maxChunkGenRequests - posListToGenerate.size(); requesting = maxChunkGenRequests - posListToGenerate.size();
for (LevelPos levelPos : posListToGenerate)
{
}
} }
//we then fill the world with the rest of the block
for (byte detailGen = LodUtil.BLOCK_DETAIL_LEVEL; detailGen <= LodUtil.REGION_DETAIL_LEVEL; detailGen++) for (byte detailGen = LodUtil.BLOCK_DETAIL_LEVEL; detailGen <= LodUtil.REGION_DETAIL_LEVEL; detailGen++)
{ {
if (requesting == 0) break; if (requesting == 0) break;
posListToGenerate.addAll(lodDim.getDataToGenerate( posListToGenerate.addAll(lodDim.getDataToGenerate(
playerBlockPosRounded.getX(), playerBlockPosRounded.getX(),
playerBlockPosRounded.getZ(), playerBlockPosRounded.getZ(),
(int) (distancesLinear[detailGen] * 1.5), DetailUtil.getDistanceGeneration(detailGen),
(int) (distancesLinear[detailGen + 1] * 1.5), DetailUtil.getDistanceGeneration(detailGen + 1),
(byte) distancesGenerators[detailGen].complexity, DetailUtil.getDistanceGenerationMode(detailGen).complexity,
(byte) 0, (byte) 0,
maxChunkGenRequests)); maxChunkGenRequests));
requesting = maxChunkGenRequests - posListToGenerate.size(); requesting = maxChunkGenRequests - posListToGenerate.size();
} }
if (LodConfig.CLIENT.distanceGenerationMode.get() != DistanceGenerationMode.NONE)
{
// determine which points in the posListToGenerate
// should actually be queued up
for (LevelPos levelPos : posListToGenerate)
{
LevelPos chunkLevelPos = levelPos.convert(LodUtil.CHUNK_DETAIL_LEVEL);
int chunkX = chunkLevelPos.posX;
int chunkZ = chunkLevelPos.posZ;
if (numberOfChunksWaitingToGenerate.get() < maxChunkGenRequests)
{
ChunkPos pos = new ChunkPos(chunkX, chunkZ);
if (positionWaitingToBeGenerated.contains(pos))
{
//ClientProxy.LOGGER.debug(pos + " asked to be generated again.");
continue;
}
// determine if this position is closer to the player
// than the previous
int newDistance = playerChunkPos.getChessboardDistance(pos);
if (newDistance < minChunkDist)
{
// this chunk is closer, clear any previous
// positions and update the new minimum distance
minChunkDist = newDistance;
// move all the old chunks into the reserve
ArrayList<ChunkPos> oldReserve = new ArrayList<>(chunksToGenReserve);
chunksToGenReserve.clear();
chunksToGenReserve.addAll(chunksToGen);
// top off reserve with whatever was in oldReerve
for (int i = 0; i < oldReserve.size(); i++)
{
if (chunksToGenReserve.size() < maxChunkGenRequests)
chunksToGenReserve.add(oldReserve.get(i));
else
break;
}
chunksToGen.clear();
chunksToGen.add(pos);
} else if (newDistance == minChunkDist)
{
// this chunk position as close as the minimum distance
if (chunksToGen.size() < maxChunkGenRequests)
{
// we are still under the number of chunks to generate
// add this position to the list
chunksToGen.add(pos);
}
} else
{
// this chunk is farther away than the minimum distance,
// add it to the reserve to make sure we always have a full reserve
chunksToGenReserve.add(pos);
}
} // lod null and can generate more chunks
} // positions to generate
if (LodConfig.CLIENT.distanceGenerationMode.get() != DistanceGenerationMode.NONE) // queue up chunks to be generated
{ if (mc.hasSingleplayerServer())
// determine which points in the posListToGenerate {
// should actually be queued up // issue #19
for (LevelPos levelPos : posListToGenerate) // TODO add a way for a server side mod to generate chunks requested here
{ ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(lodDim.dimension);
LevelPos chunkLevelPos = levelPos.convert((byte) 3);
int chunkX = Math.floorDiv(chunkLevelPos.posX, 2);
int chunkZ = Math.floorDiv(chunkLevelPos.posZ, 2);
if (numberOfChunksWaitingToGenerate.get() < maxChunkGenRequests) // make sure we have as many chunks to generate as we are allowed
{ if (chunksToGen.size() < maxChunkGenRequests)
ChunkPos pos = new ChunkPos(chunkX, chunkZ); {
Iterator<ChunkPos> reserveIterator = chunksToGenReserve.iterator();
while (chunksToGen.size() < maxChunkGenRequests && reserveIterator.hasNext())
{
chunksToGen.add(reserveIterator.next());
}
}
if (positionWaitingToBeGenerated.contains(pos)) // start chunk generation
{ for (ChunkPos chunkPos : chunksToGen)
ClientProxy.LOGGER.debug(pos + " asked to be generated again."); {
continue; // don't add null chunkPos (which shouldn't happen anyway)
} // or add more to the generation queue
if (chunkPos == null || numberOfChunksWaitingToGenerate.get() >= maxChunkGenRequests)
continue;
// determine if this position is closer to the player positionWaitingToBeGenerated.add(chunkPos);
// than the previous numberOfChunksWaitingToGenerate.addAndGet(1);
int newDistance = playerChunkPos.getChessboardDistance(pos); LodNodeGenWorker genWorker = new LodNodeGenWorker(chunkPos, DistanceGenerationMode.SURFACE, LodDetail.FULL, renderer, LodQuadTreeNodeBuilder, this, lodDim, serverWorld);
WorldWorkerManager.addWorker(genWorker);
if (newDistance < minChunkDist) }
{ }
// this chunk is closer, clear any previous } // if distanceGenerationMode != DistanceGenerationMode.NONE
// positions and update the new minimum distance
minChunkDist = newDistance;
// move all the old chunks into the reserve
ArrayList<ChunkPos> oldReserve = new ArrayList<>(chunksToGenReserve);
chunksToGenReserve.clear();
chunksToGenReserve.addAll(chunksToGen);
// top off reserve with whatever was in oldReerve
for (int i = 0; i < oldReserve.size(); i++)
{
if (chunksToGenReserve.size() < maxChunkGenRequests)
chunksToGenReserve.add(oldReserve.get(i));
else
break;
}
chunksToGen.clear();
chunksToGen.add(pos);
}
else if (newDistance == minChunkDist)
{
// this chunk position as close as the minimum distance
if (chunksToGen.size() < maxChunkGenRequests)
{
// we are still under the number of chunks to generate
// add this position to the list
chunksToGen.add(pos);
}
}
else
{
// this chunk is farther away than the minimum distance,
// add it to the reserve to make sure we always have a full reserve
chunksToGenReserve.add(pos);
}
} // lod null and can generate more chunks
} // positions to generate
// queue up chunks to be generated
if (mc.hasSingleplayerServer())
{
// issue #19
// TODO add a way for a server side mod to generate chunks requested here
ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(lodDim.dimension);
// make sure we have as many chunks to generate as we are allowed
if (chunksToGen.size() < maxChunkGenRequests)
{
Iterator<ChunkPos> reserveIterator = chunksToGenReserve.iterator();
while (chunksToGen.size() < maxChunkGenRequests && reserveIterator.hasNext())
{
chunksToGen.add(reserveIterator.next());
}
}
// start chunk generation
for (ChunkPos chunkPos : chunksToGen)
{
// don't add null chunkPos (which shouldn't happen anyway)
// or add more to the generation queue
if (chunkPos == null || numberOfChunksWaitingToGenerate.get() >= maxChunkGenRequests)
continue;
positionWaitingToBeGenerated.add(chunkPos);
numberOfChunksWaitingToGenerate.addAndGet(1);
LodNodeGenWorker genWorker = new LodNodeGenWorker(chunkPos, DistanceGenerationMode.SURFACE, LodDetail.FULL, renderer, LodQuadTreeNodeBuilder, this, lodDim, serverWorld);
WorldWorkerManager.addWorker(genWorker);
}
}
} // if distanceGenerationMode != DistanceGenerationMode.NONE
// finish the buffer building // finish the buffer building
@@ -434,15 +424,13 @@ public class LodBufferBuilder
//ClientProxy.LOGGER.info("Buffer Build time: " + buildTime + " ms"); //ClientProxy.LOGGER.info("Buffer Build time: " + buildTime + " ms");
// mark that the buildable buffers as ready to swap // mark that the buildable buffers as ready to swap
switchVbos = true; switchVbos = true;
} } catch (Exception e)
catch (Exception e) {
{ ClientProxy.LOGGER.warn("\"LodNodeBufferBuilder.generateLodBuffersAsync\" ran into trouble: ");
ClientProxy.LOGGER.warn("\"LodNodeBufferBuilder.generateLodBuffersAsync\" ran into trouble: "); e.printStackTrace();
e.printStackTrace(); } finally
} {
finally
{
// regardless of if we successfully created the buffers // regardless of if we successfully created the buffers
// we are done generating. // we are done generating.
generatingBuffers = false; generatingBuffers = false;
@@ -472,11 +460,11 @@ public class LodBufferBuilder
*/ */
private boolean isCoordInCenterArea(int i, int j, int centerCoordinate) private boolean isCoordInCenterArea(int i, int j, int centerCoordinate)
{ {
return (i >= centerCoordinate - mc.options.renderDistance return (i >= centerCoordinate - (mc.options.renderDistance + 2)
&& i <= centerCoordinate + mc.options.renderDistance) && i <= centerCoordinate + (mc.options.renderDistance + 2))
&& &&
(j >= centerCoordinate - mc.options.renderDistance (j >= centerCoordinate - (mc.options.renderDistance + 2)
&& j <= centerCoordinate + mc.options.renderDistance); && j <= centerCoordinate + (mc.options.renderDistance + 2));
} }
@@ -27,13 +27,9 @@ import com.seibel.lod.objects.LevelPos;
import com.seibel.lod.objects.LodDataPoint; import com.seibel.lod.objects.LodDataPoint;
import com.seibel.lod.objects.LodDimension; import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodWorld; import com.seibel.lod.objects.LodWorld;
//import com.seibel.lod.util.BiomeColorsUtils;
import com.seibel.lod.util.LodThreadFactory; import com.seibel.lod.util.LodThreadFactory;
import com.seibel.lod.util.LodUtil; import com.seibel.lod.util.LodUtil;
//import kaptainwutax.biomeutils.source.OverworldBiomeSource;
//import kaptainwutax.mcutils.version.MCVersion;
//import kaptainwutax.terrainutils.TerrainGenerator;
import net.minecraft.block.AbstractPlantBlock; import net.minecraft.block.AbstractPlantBlock;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
@@ -42,7 +38,6 @@ import net.minecraft.block.GrassBlock;
import net.minecraft.block.IGrowable; import net.minecraft.block.IGrowable;
import net.minecraft.block.LeavesBlock; import net.minecraft.block.LeavesBlock;
import net.minecraft.block.material.MaterialColor; import net.minecraft.block.material.MaterialColor;
//import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.DimensionType; import net.minecraft.world.DimensionType;
import net.minecraft.world.IWorld; import net.minecraft.world.IWorld;
import net.minecraft.world.biome.Biome; import net.minecraft.world.biome.Biome;
@@ -190,52 +185,6 @@ public class LodBuilder
} }
} }
/**
* Creates a LodChunk for a chunk in the given world.
*
* @throws IllegalArgumentException thrown if either the chunk or world is null.
*/
/**TODO if we want to test biome utils and terrain utils
public void generateLodNodeFromChunk(LodDimension lodDim, ChunkPos chunkPos , LodDetail detail, long seed)
throws IllegalArgumentException
{
if (chunkPos == null)
throw new IllegalArgumentException("generateLodFromChunk given a null chunk pos");
int startX;
int startZ;
int endX;
int endZ;
Color color;
short height;
short depth;
LevelPos levelPos;
LodDataPoint data;
OverworldBiomeSource biomeSource = new OverworldBiomeSource(MCVersion.v1_16_5, seed);
TerrainGenerator terrainGenerator= TerrainGenerator.of(biomeSource);
for (int i = 0; i < detail.dataPointLengthCount * detail.dataPointLengthCount; i++)
{
startX = detail.startX[i];
startZ = detail.startZ[i];
endX = detail.endX[i];
endZ = detail.endZ[i];
color = generateLodColorForArea(biomeSource, chunkPos, startX, startZ, endX, endZ);
height = determineHeightPoint(terrainGenerator, chunkPos, startX, startZ, endX, endZ);
levelPos = new LevelPos((byte) 0,
chunkPos.x * 16 + startX,
chunkPos.z * 16 + startZ);
data = new LodDataPoint(height, 0, color);
lodDim.addData(levelPos.convert((byte) detail.detailLevel),
data,
DistanceGenerationMode.SURFACE,
true,
false);
}
}*/
// =====================// // =====================//
// constructor helpers // // constructor helpers //
@@ -362,26 +311,6 @@ public class LodBuilder
return highest; return highest;
} }
/**
* Find the highest point from the Top
*/
/**TODO if we want to test biome utils and terrain utils
private short determineHeightPoint(TerrainGenerator terrainGenerator, ChunkPos chunkPos, int startX, int startZ, int endX, int endZ)
{
short newHeight = 0;
int num = 0;
for (int x = startX; x < endX; x++)
{
for (int z = startZ; z < endZ; z++)
{
num++;
newHeight += (short) terrainGenerator.getFirstHeightInColumn(chunkPos.x*16 + x,chunkPos.z*16 + z, TerrainGenerator.WORLD_SURFACE_WG);;
}
}
return (short) (newHeight/num);
}*/
/** /**
* Generate the color for the given chunk using biome water color, foliage * Generate the color for the given chunk using biome water color, foliage
* color, and grass color. * color, and grass color.
@@ -481,39 +410,6 @@ public class LodBuilder
return new Color(red, green, blue); return new Color(red, green, blue);
} }
/**TODO if we want to test biome utils and terrain utils
private Color generateLodColorForArea(OverworldBiomeSource biomeSource, ChunkPos chunkPos, int startX, int startZ, int endX,
int endZ)
{
int numbOfBlocks = 0;
int red = 0;
int green = 0;
int blue = 0;
for (int x = startX; x < endX; x++)
{
for (int z = startZ; z < endZ; z++)
{
Color color = BiomeColorsUtils.getColorFromBiomeManual(biomeSource.getBiome(chunkPos.x*16 + x,0,chunkPos.z*16 + z));
red += color.getBlue();
green += color.getGreen();
blue += color.getBlue();
}
}
if (numbOfBlocks == 0)
numbOfBlocks = 1;
red /= numbOfBlocks;
green /= numbOfBlocks;
blue /= numbOfBlocks;
return new Color(red, green, blue);
}
*/
/** /**
* Returns a color int for a given block. * Returns a color int for a given block.
*/ */
@@ -0,0 +1,14 @@
package com.seibel.lod.enums;
/**
* @author Leonardo Amato
* @version 22-08-2021
*/
public enum DistanceCalculatorType
{
/** different Lod detail render and generate linearly to the distance */
LINEAR,
/** different Lod detail render and generate quadratically to the distance */
QUADRATIC,
}
@@ -34,14 +34,14 @@ package com.seibel.lod.enums;
public enum DistanceGenerationMode public enum DistanceGenerationMode
{ {
/** Don't generate anything */ /** Don't generate anything */
NONE(0), NONE((byte) 0),
/** Only generate the biomes and use biome /** Only generate the biomes and use biome
* grass/foliage color, water color, or ice color * grass/foliage color, water color, or ice color
* to generate the color. * to generate the color.
* Doesn't generate height, everything is shown at sea level. * Doesn't generate height, everything is shown at sea level.
* Multithreaded - Fastest (2-5 ms) */ * Multithreaded - Fastest (2-5 ms) */
BIOME_ONLY(1), BIOME_ONLY((byte) 1),
/** /**
* Same as BIOME_ONLY, except instead * Same as BIOME_ONLY, except instead
@@ -49,32 +49,32 @@ public enum DistanceGenerationMode
* different biome types (mountain, ocean, forest, etc.) * different biome types (mountain, ocean, forest, etc.)
* use predetermined heights to simulate having height data. * use predetermined heights to simulate having height data.
*/ */
BIOME_ONLY_SIMULATE_HEIGHT(2), BIOME_ONLY_SIMULATE_HEIGHT((byte) 2),
/** Generate the world surface, /** Generate the world surface,
* this does NOT include caves, trees, * this does NOT include caves, trees,
* or structures. * or structures.
* Multithreaded - Faster (10-20 ms) */ * Multithreaded - Faster (10-20 ms) */
SURFACE(3), SURFACE((byte) 3),
/** Generate everything except structures. /** Generate everything except structures.
* NOTE: This may cause world generation bugs or instability, * NOTE: This may cause world generation bugs or instability,
* since some features cause concurrentModification exceptions. * since some features cause concurrentModification exceptions.
* Multithreaded - Fast (15-20 ms) */ * Multithreaded - Fast (15-20 ms) */
FEATURES(4), FEATURES((byte) 4),
/** Ask the server to generate/load each chunk. /** Ask the server to generate/load each chunk.
* This is the most compatible, but causes server/simulation lag. * This is the most compatible, but causes server/simulation lag.
* This will also show player made structures if you * This will also show player made structures if you
* are adding the mod to a pre-existing world. * are adding the mod to a pre-existing world.
* Singlethreaded - Slow (15-50 ms, with spikes up to 200 ms) */ * Singlethreaded - Slow (15-50 ms, with spikes up to 200 ms) */
SERVER(5); SERVER((byte) 5);
/** The higher the number the more complete the generation is. */ /** The higher the number the more complete the generation is. */
public final int complexity; public final byte complexity;
DistanceGenerationMode(int complexity) DistanceGenerationMode(byte complexity)
{ {
this.complexity = complexity; this.complexity = complexity;
} }
@@ -20,18 +20,13 @@ package com.seibel.lod.handlers;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import com.seibel.lod.enums.*;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.io.WritingMode; import com.electronwill.nightconfig.core.io.WritingMode;
import com.seibel.lod.ModInfo; import com.seibel.lod.ModInfo;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.FogDistance;
import com.seibel.lod.enums.FogDrawOverride;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.enums.LodTemplate;
import com.seibel.lod.enums.ShadingMode;
import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.common.ForgeConfigSpec;
import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.eventbus.api.SubscribeEvent;
@@ -77,6 +72,8 @@ public class LodConfig
*/ */
public ForgeConfigSpec.IntValue lodChunkRadiusMultiplier; public ForgeConfigSpec.IntValue lodChunkRadiusMultiplier;
public ForgeConfigSpec.EnumValue<DistanceCalculatorType> lodDistanceCalculatorType;
public ForgeConfigSpec.IntValue lodQuality; public ForgeConfigSpec.IntValue lodQuality;
public ForgeConfigSpec.IntValue lodChunkRenderDistane; public ForgeConfigSpec.IntValue lodChunkRenderDistane;
@@ -160,6 +157,29 @@ public class LodConfig
+ " of LODs in each cardinal direction. \n") + " of LODs in each cardinal direction. \n")
.defineInRange("lodChunkRadiusMultiplier", 8, 2, 16); .defineInRange("lodChunkRadiusMultiplier", 8, 2, 16);
lodDistanceCalculatorType = builder
.comment("\n\n"
+ " " + DistanceCalculatorType.LINEAR + " \n"
+ " with LINEAR calculator the quality of block decrease \n"
+ " linearly to the distance of the player \n"
+ "\n"
+ " " + DistanceCalculatorType.QUADRATIC + " \n"
+ " with LINEAR calculator the quality of block decrease \n"
+ " quadratically to the distance of the player \n")
.defineEnum("lodDistanceComputation", DistanceCalculatorType.LINEAR);
lodQuality = builder
.comment("\n\n"
+ " this value is multiplied by 128 and determine \n"
+ " how much the quality decrease over distance \n")
.defineInRange("lodChunkRadiusMultiplier", 1, 1, 4);
lodChunkRenderDistane = builder
.comment("\n\n"
+ " This is the render distance of the mod \n")
.defineInRange("lodChunkRadiusMultiplier", 128, 32, 128);
distanceGenerationMode = builder distanceGenerationMode = builder
.comment("\n\n" .comment("\n\n"
+ " Note: The times listed here are the amount of time it took \n" + " Note: The times listed here are the amount of time it took \n"
@@ -321,7 +321,7 @@ public class LodDimension
region = new LodRegion((byte) 0, regionPos); region = new LodRegion((byte) 0, regionPos);
addOrOverwriteRegion(region); addOrOverwriteRegion(region);
} }
boolean nodeAdded = region.setData(levelPos, lodDataPoint, (byte) generationMode.complexity, true); boolean nodeAdded = region.setData(levelPos, lodDataPoint, generationMode.complexity, true);
// only save valid LODs to disk // only save valid LODs to disk
if (!dontSave && fileHandler != null) if (!dontSave && fileHandler != null)
{ {
@@ -205,6 +205,8 @@ public class LodRegion implements Serializable
} }
/** /**
* This method will return all the levelPos that are renderable according to the requisite given in input
*
* @return * @return
*/ */
public List<Map.Entry<LevelPos,Integer>> getDataToGenerate(int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel, int dataNumber) public List<Map.Entry<LevelPos,Integer>> getDataToGenerate(int playerPosX, int playerPosZ, int start, int end, byte generation, byte detailLevel, int dataNumber)
@@ -17,17 +17,13 @@
*/ */
package com.seibel.lod.proxy; package com.seibel.lod.proxy;
import com.seibel.lod.enums.*;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import com.seibel.lod.builders.LodBufferBuilder; import com.seibel.lod.builders.LodBufferBuilder;
import com.seibel.lod.builders.LodBuilder; import com.seibel.lod.builders.LodBuilder;
import com.seibel.lod.builders.worldGeneration.LodNodeGenWorker; import com.seibel.lod.builders.worldGeneration.LodNodeGenWorker;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.FogDistance;
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.handlers.LodConfig;
import com.seibel.lod.objects.LodDimension; import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodWorld; import com.seibel.lod.objects.LodWorld;
@@ -151,6 +147,10 @@ public class ClientProxy
LodConfig.CLIENT.distanceGenerationMode.set(DistanceGenerationMode.FEATURES); LodConfig.CLIENT.distanceGenerationMode.set(DistanceGenerationMode.FEATURES);
LodConfig.CLIENT.allowUnstableFeatureGeneration.set(false); LodConfig.CLIENT.allowUnstableFeatureGeneration.set(false);
LodConfig.CLIENT.lodChunkRenderDistane.set(96);
LodConfig.CLIENT.lodDistanceCalculatorType.set(DistanceCalculatorType.LINEAR);
LodConfig.CLIENT.lodQuality.set(1);
LodConfig.CLIENT.allowUnstableFeatureGeneration.set(false);
// has to be set in the config file // has to be set in the config file
// LodConfig.CLIENT.numberOfWorldGenerationThreads.set(16); // LodConfig.CLIENT.numberOfWorldGenerationThreads.set(16);
@@ -229,11 +229,11 @@ public class LodRenderer
// determine how far the game's render distance is currently set // determine how far the game's render distance is currently set
//farPlaneBlockDistance = mc.options.renderDistance * LodUtil.CHUNK_WIDTH; //farPlaneBlockDistance = mc.options.renderDistance * LodUtil.CHUNK_WIDTH;
farPlaneBlockDistance = 8 * LodUtil.CHUNK_WIDTH; farPlaneBlockDistance = LodConfig.CLIENT.lodChunkRenderDistane.get() * LodUtil.CHUNK_WIDTH;
// set how how far the LODs will go // set how how far the LODs will go
//int numbChunksWide = mc.options.renderDistance * 2 * LodConfig.CLIENT.lodChunkRadiusMultiplier.get(); //int numbChunksWide = mc.options.renderDistance * 2 * LodConfig.CLIENT.lodChunkRadiusMultiplier.get();
int numbChunksWide = 8 * 2 * LodConfig.CLIENT.lodChunkRadiusMultiplier.get() + 1; int numbChunksWide =LodConfig.CLIENT.lodChunkRenderDistane.get() * 2;
// determine which LODs should not be rendered close to the player // determine which LODs should not be rendered close to the player
HashSet<ChunkPos> chunkPosToSkip = getNearbyLodChunkPosToSkip(lodDim, player.blockPosition()); HashSet<ChunkPos> chunkPosToSkip = getNearbyLodChunkPosToSkip(lodDim, player.blockPosition());
@@ -461,12 +461,12 @@ public class LodRenderer
{ {
if (fogQuality == FogQuality.FANCY) if (fogQuality == FogQuality.FANCY)
{ {
RenderSystem.fogStart(farPlaneBlockDistance * 0.85f * LodConfig.CLIENT.lodChunkRadiusMultiplier.get()); RenderSystem.fogStart(farPlaneBlockDistance * 0.85f);
RenderSystem.fogEnd(farPlaneBlockDistance * 1.0f * LodConfig.CLIENT.lodChunkRadiusMultiplier.get()); RenderSystem.fogEnd(farPlaneBlockDistance * 1.0f);
} else if (fogQuality == FogQuality.FAST) } else if (fogQuality == FogQuality.FAST)
{ {
RenderSystem.fogStart(farPlaneBlockDistance * 0.5f * LodConfig.CLIENT.lodChunkRadiusMultiplier.get()); RenderSystem.fogStart(farPlaneBlockDistance * 0.5f);
RenderSystem.fogEnd(farPlaneBlockDistance * 0.75f * LodConfig.CLIENT.lodChunkRadiusMultiplier.get()); RenderSystem.fogEnd(farPlaneBlockDistance * 0.75f);
} }
} }
@@ -1,719 +0,0 @@
/*
* This file is part of the LOD Mod, licensed under the GNU GPL v3 License.
*
* Copyright (C) 2020 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* 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.util;
import net.minecraft.block.Blocks;
import net.minecraft.world.biome.*;
import java.awt.*;
public class BiomeColorsUtils {
//public static OverworldBiomeSource overworldBiomeSource = new OverworldBiomeSource(MCVersion.v1_16_4, 64971835648254);
public static Color getColorFromBiome(Biome biome,double x, double y){
int color = 0;
switch(biome.getBiomeCategory()) {
case BEACH:
case DESERT:
color = Blocks.SAND.defaultMaterialColor().col;
break;
case EXTREME_HILLS:
color = Blocks.SNOW.defaultMaterialColor().col;
break;
case NONE:
break;
case FOREST:
case JUNGLE:
case TAIGA:
color = biome.getFoliageColor();
break;
case MUSHROOM:
color = Blocks.MYCELIUM.defaultMaterialColor().col;
break;
case PLAINS:
case SAVANNA:
color = biome.getGrassColor(x,y);
break;
case OCEAN:
case RIVER:
case SWAMP:
color = biome.getWaterColor();
break;
case ICY:
color = Blocks.PACKED_ICE.defaultMaterialColor().col;
break;
case THEEND:
color = Blocks.END_STONE.defaultMaterialColor().col;
break;
case NETHER:
color = Blocks.NETHERRACK.defaultMaterialColor().col;
break;
case MESA:
color = Blocks.RED_SAND.defaultMaterialColor().col;
break;
default:
color = 0;
}
return new Color(color);
}
public static Color getColorFromBiome(Biome biome){
int color = 0;
switch(biome.getBiomeCategory()) {
case BEACH:
case DESERT:
color = Blocks.SAND.defaultMaterialColor().col;
break;
case EXTREME_HILLS:
color = Blocks.SNOW.defaultMaterialColor().col;
break;
case FOREST:
case SAVANNA:
case JUNGLE:
case TAIGA:
color = biome.getFoliageColor();
break;
case MUSHROOM:
color = Blocks.MYCELIUM.defaultMaterialColor().col;
break;
case PLAINS:
color = Blocks.GRASS_BLOCK.defaultMaterialColor().col;
break;
case OCEAN:
case RIVER:
case SWAMP:
color = biome.getWaterColor();
break;
case ICY:
color = Blocks.PACKED_ICE.defaultMaterialColor().col;
break;
case THEEND:
color = Blocks.END_STONE.defaultMaterialColor().col;
break;
case NETHER:
color = Blocks.NETHERRACK.defaultMaterialColor().col;
break;
case MESA:
color = Blocks.RED_SAND.defaultMaterialColor().col;
break;
case NONE:
default:
color = 0;
}
return new Color(color);
}
/**
* methods that gives the ChunkBase color of biomes
* @param biome to check
* @return color of the biome
*/
public static Color getColorFromIdRealistic(kaptainwutax.biomeutils.biome.Biome biome){
Biome.Builder builder = new Biome.Builder();
int color = 0;
switch(biome.getCategory()) {
case BEACH:
case DESERT:
color = Blocks.SAND.defaultMaterialColor().col;
break;
case EXTREME_HILLS:
color = Blocks.SNOW.defaultMaterialColor().col;
break;
case FOREST:
builder.biomeCategory(Biome.Category.FOREST);
color = builder.build().getFoliageColor();
break;
case SAVANNA:
builder.biomeCategory(Biome.Category.SAVANNA);
color = builder.build().getFoliageColor();
break;
case JUNGLE:
builder.biomeCategory(Biome.Category.JUNGLE);
color = builder.build().getFoliageColor();
break;
case TAIGA:
builder.biomeCategory(Biome.Category.TAIGA);
color = builder.build().getFoliageColor();
break;
case MUSHROOM:
color = Blocks.MYCELIUM.defaultMaterialColor().col;
break;
case PLAINS:
color = Blocks.GRASS_BLOCK.defaultMaterialColor().col;
break;
case OCEAN:
builder.biomeCategory(Biome.Category.OCEAN);
color = builder.build().getWaterColor();
break;
case RIVER:
builder.biomeCategory(Biome.Category.RIVER);
color = builder.build().getWaterColor();
break;
case SWAMP:
builder.biomeCategory(Biome.Category.SWAMP);
color = builder.build().getWaterColor();
break;
case ICY:
color = Blocks.PACKED_ICE.defaultMaterialColor().col;
break;
case THE_END:
color = Blocks.END_STONE.defaultMaterialColor().col;
break;
case NETHER:
color = Blocks.NETHERRACK.defaultMaterialColor().col;
break;
case BADLANDS_PLATEAU:
case MESA:
color = Blocks.RED_SAND.defaultMaterialColor().col;
break;
case NONE:
default:
color = 0;
}
return new Color(color);
}
/**
* methods that gives the ChunkBase color of biomes
* @param biome to check
* @return color of the biome
*/
public static Color getColorFromBiomeBlock(kaptainwutax.biomeutils.biome.Biome biome){
int color = 0;
switch(biome.getCategory()) {
case BEACH:
case DESERT:
color = Blocks.SAND.defaultMaterialColor().col;
break;
case EXTREME_HILLS:
color = Blocks.SNOW.defaultMaterialColor().col;
break;
case FOREST:
color = Blocks.OAK_LEAVES.defaultMaterialColor().col;
break;
case SAVANNA:
color = Blocks.ACACIA_LEAVES.defaultMaterialColor().col;
break;
case JUNGLE:
color = Blocks.JUNGLE_LEAVES.defaultMaterialColor().col;
break;
case TAIGA:
color = Blocks.SPRUCE_LEAVES.defaultMaterialColor().col;
break;
case MUSHROOM:
color = Blocks.MYCELIUM.defaultMaterialColor().col;
break;
case PLAINS:
color = Blocks.GRASS_BLOCK.defaultMaterialColor().col;
break;
case OCEAN:
case RIVER:
color = Blocks.WATER.defaultMaterialColor().col;
case SWAMP:
color = Blocks.LILY_PAD.defaultMaterialColor().col;
break;
case ICY:
color = Blocks.PACKED_ICE.defaultMaterialColor().col;
break;
case THE_END:
color = Blocks.END_STONE.defaultMaterialColor().col;
break;
case NETHER:
color = Blocks.NETHERRACK.defaultMaterialColor().col;
break;
case BADLANDS_PLATEAU:
case MESA:
color = Blocks.RED_SAND.defaultMaterialColor().col;
break;
case NONE:
default:
color = 0;
}
return new Color(color);
}
/**
* methods that gives the ChunkBase color of biomes
* @param biome to check
* @return color of the biome
*/
public static Color getColorFromBiomeManual(kaptainwutax.biomeutils.biome.Biome biome){
Color color;
switch(biome.getCategory()) {
case BEACH:
case DESERT:
color = new Color(220,214,170);
break;
case EXTREME_HILLS:
color = new Color(81,129,60);
break;
case FOREST:
color = new Color(81,129,60);
break;
case SAVANNA:
color = new Color(119,113,53);
break;
case JUNGLE:
color = new Color(41,141,4);
break;
case TAIGA:
color = new Color(70,95,68);
break;
case MUSHROOM:
color = new Color(123,105,109);
break;
case PLAINS:
color = new Color(96,125,59);
break;
case OCEAN:
case RIVER:
color = new Color(54,73,229);
break;
case SWAMP:
color = new Color(83,86,67);
break;
case ICY:
color = new Color(199,217,254);
break;
case THE_END:
color = new Color(100,100,0);
break;
case NETHER:
color = new Color(100,0,0);
break;
case BADLANDS_PLATEAU:
case MESA:
color = new Color(188,103,39);
break;
case NONE:
color = new Color(96,125,59);
break;
default:
color = new Color(0,0,0,0);
}
return color;
}
/**
* methods that gives the ChunkBase color of biomes
* @param biomeId id of the biome
* @return color of the biome
*/
public static Color getColorFromIdCB(int biomeId){
int red=0;
int green=0;
int blue=0;
switch(biomeId) {
case 0:
red = 0;
green = 0;
blue = 112;
break;
case 1:
red = 141;
green = 179;
blue = 96;
break;
case 2:
red = 250;
green = 148;
blue = 24;
break;
case 3:
red = 96;
green = 96;
blue = 96;
break;
case 4:
red = 5;
green = 102;
blue = 33;
break;
case 5:
red = 11;
green = 2;
blue = 89;
break;
case 6:
red = 7;
green = 249;
blue = 178;
break;
case 7:
red = 0;
green = 0;
blue = 255;
break;
case 8:
red = 255;
green = 0;
blue = 0;
break;
case 9:
red = 128;
green = 128;
blue = 255;
break;
case 10:
red = 112;
green = 112;
blue = 214;
break;
case 11:
red = 160;
green = 160;
blue = 255;
break;
case 12:
red = 255;
green = 255;
blue = 255;
break;
case 13:
red = 160;
green = 160;
blue = 160;
break;
case 14:
red = 255;
green = 0;
blue = 255;
break;
case 15:
red = 160;
green = 0;
blue = 255;
break;
case 16:
red = 250;
green = 222;
blue = 85;
break;
case 17:
red = 210;
green = 95;
blue = 18;
break;
case 18:
red = 34;
green = 85;
blue = 28;
break;
case 19:
red = 22;
green = 57;
blue = 51;
break;
case 20:
red = 114;
green = 120;
blue = 154;
break;
case 21:
red = 83;
green = 123;
blue = 9;
break;
case 22:
red = 44;
green = 66;
blue = 5;
break;
case 23:
red = 98;
green = 139;
blue = 23;
break;
case 24:
red = 0;
green = 0;
blue = 48;
break;
case 25:
red = 162;
green = 162;
blue = 132;
break;
case 26:
red = 250;
green = 240;
blue = 192;
break;
case 27:
red = 48;
green = 116;
blue = 68;
break;
case 28:
red = 31;
green = 5;
blue = 50;
break;
case 29:
red = 64;
green = 81;
blue = 26;
break;
case 30:
red = 49;
green = 85;
blue = 74;
break;
case 31:
red = 36;
green = 63;
blue = 54;
break;
case 32:
red = 89;
green = 102;
blue = 81;
break;
case 33:
red = 69;
green = 7;
blue = 62;
break;
case 34:
red = 80;
green = 112;
blue = 80;
break;
case 35:
red = 189;
green = 18;
blue = 95;
break;
case 36:
red = 167;
green = 157;
blue = 100;
break;
case 37:
red = 217;
green = 69;
blue = 21;
break;
case 38:
red = 17;
green = 151;
blue = 101;
break;
case 39:
red = 202;
green = 140;
blue = 101;
break;
case 40:
red = 128;
green = 128;
blue = 255;
break;
case 41:
red = 128;
green = 128;
blue = 255;
break;
case 42:
red = 128;
green = 128;
blue = 255;
break;
case 43:
red = 128;
green = 128;
blue = 255;
break;
case 44:
red = 0;
green = 0;
blue = 172;
break;
case 45:
red = 0;
green = 0;
blue = 144;
break;
case 46:
red = 32;
green = 32;
blue = 112;
break;
case 47:
red = 0;
green = 0;
blue = 80;
break;
case 48:
red = 0;
green = 0;
blue = 64;
break;
case 49:
red = 32;
green = 32;
blue = 56;
break;
case 50:
red = 64;
green = 64;
blue = 144;
break;
case 127:
red = 0;
green = 0;
blue = 0;
break;
case 129:
red = 181;
green = 219;
blue = 136;
break;
case 130:
red = 255;
green = 188;
blue = 64;
break;
case 131:
red = 136;
green = 136;
blue = 136;
break;
case 132:
red = 45;
green = 142;
blue = 73;
break;
case 133:
red = 51;
green = 142;
blue = 19;
break;
case 134:
red = 47;
green = 255;
blue = 18;
break;
case 140:
red = 180;
green = 20;
blue = 220;
break;
case 149:
red = 123;
green = 13;
blue = 49;
break;
case 151:
red = 138;
green = 179;
blue = 63;
break;
case 155:
red = 88;
green = 156;
blue = 108;
break;
case 156:
red = 71;
green = 15;
blue = 90;
break;
case 157:
red = 104;
green = 121;
blue = 66;
break;
case 158:
red = 89;
green = 125;
blue = 114;
break;
case 160:
red = 129;
green = 142;
blue = 121;
break;
case 161:
red = 109;
green = 119;
blue = 102;
break;
case 162:
red = 120;
green = 52;
blue = 120;
break;
case 163:
red = 229;
green = 218;
blue = 135;
break;
case 164:
red = 207;
green = 197;
blue = 140;
break;
case 165:
red = 255;
green = 109;
blue = 61;
break;
case 166:
red = 216;
green = 191;
blue = 141;
break;
case 167:
red = 242;
green = 180;
blue = 141;
break;
case 168:
red = 118;
green = 142;
blue = 20;
break;
case 169:
red = 59;
green = 71;
blue = 10;
break;
case 170:
red = 82;
green = 41;
blue = 33;
break;
case 171:
red = 221;
green = 8;
blue = 8;
break;
case 172:
red = 73;
green = 144;
blue = 123;
break;
default:
red = 255;
green = 0;
blue = 0;
}
return new Color(red, green, blue);
}
}
@@ -0,0 +1,57 @@
package com.seibel.lod.util;
import com.seibel.lod.enums.DistanceCalculatorType;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.enums.LodQuality;
import com.seibel.lod.handlers.LodConfig;
public class DetailUtil
{
private static double genMultiplier = 1.5;
private static final int maxDetail = LodUtil.REGION_DETAIL_LEVEL + 1;
private static final int minDistance = 0;
private static final int maxDistance = LodConfig.CLIENT.lodChunkRenderDistane.get() * 16;
private static DistanceGenerationMode[] distancesGenerators = {
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE,
DistanceGenerationMode.SURFACE};
public static int getDistanceRendering(int detail)
{
int distance = 0;
int initial = LodConfig.CLIENT.lodQuality.get() * 128;
switch (LodConfig.CLIENT.lodDistanceCalculatorType.get())
{
case LINEAR:
distance = (detail * initial);
break;
case QUADRATIC:
if (detail == 0)
distance = minDistance;
else if(detail == maxDetail)
distance = maxDistance;
else
distance = (int) (Math.pow(2, detail) * initial);
break;
}
return distance;
}
public static int getDistanceGeneration(int detail)
{
return (int) (getDistanceRendering(detail) * genMultiplier);
}
public static DistanceGenerationMode getDistanceGenerationMode(int detail)
{
return distancesGenerators[detail];
}
}