- * May have to wait for the bufferLock to open.
- */
- public void setupBuffers(int numbRegionsWide, int bufferMaxCapacity)
- {
- bufferLock.lock();
-
- previousRegionWidth = numbRegionsWide;
- previousBufferSize = bufferMaxCapacity;
-
-
- buildableBuffers = new BufferBuilder[numbRegionsWide][numbRegionsWide];
-
- buildableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide];
- drawableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide];
-
- for (int x = 0; x < numbRegionsWide; x++)
- {
- for (int z = 0; z < numbRegionsWide; z++)
- {
- buildableBuffers[x][z] = new BufferBuilder(bufferMaxCapacity);
- buildableVbos[x][z] = new VertexBuffer(LodRenderer.LOD_VERTEX_FORMAT);
- drawableVbos[x][z] = new VertexBuffer(LodRenderer.LOD_VERTEX_FORMAT);
- }
- }
-
- bufferLock.unlock();
- }
-
- /**
- * sets the buffers and Vbos to null, forcing them to be recreated.
- *
- * May have to wait for the bufferLock to open.
- */
- public void destroyBuffers()
- {
- bufferLock.lock();
-
- buildableBuffers = null;
- buildableVbos = null;
- drawableVbos = null;
-
- bufferLock.unlock();
- }
-
-
- /**
- * Calls begin on each of the buildable BufferBuilders.
- */
- private void startBuffers()
- {
- for (int x = 0; x < buildableBuffers.length; x++)
- for (int z = 0; z < buildableBuffers.length; z++)
- buildableBuffers[x][z].begin(GL11.GL_QUADS, LodRenderer.LOD_VERTEX_FORMAT);
- }
-
- /**
- * Calls end on each of the buildable BufferBuilders.
- */
- private void closeBuffers()
- {
- for (int x = 0; x < buildableBuffers.length; x++)
- for (int z = 0; z < buildableBuffers.length; z++)
- if (buildableBuffers[x][z] != null && buildableBuffers[x][z].building())
- buildableBuffers[x][z].end();
- }
-
- /**
- * Called from the LodRenderer to create the
- * BufferBuilders at the right size.
- */
- private void uploadBuffers()
- {
- for (int x = 0; x < buildableVbos.length; x++)
- {
- for (int z = 0; z < buildableVbos.length; z++)
- {
- buildableVbos[x][z].upload(buildableBuffers[x][z]);
- }
- }
- }
-
-
- /**
- * Get the newly created VBOs
- */
- public VertexBuffer[][] getVertexBuffers()
- {
- // don't wait for the lock to open
- // since this is called on the main render thread
- if (bufferLock.tryLock())
- {
- VertexBuffer[][] tmp = drawableVbos;
- drawableVbos = buildableVbos;
- buildableVbos = tmp;
-
- // the vbos have been swapped
- switchVbos = false;
- bufferLock.unlock();
- }
-
- return drawableVbos;
- }
-
- /**
- * If this is true the buildable near and far
- * buffers have been generated and are ready to be
- * sent to the LodRenderer.
- */
- public boolean newBuffersAvaliable()
- {
- return switchVbos;
- }
+ /**
+ * if this is true new LOD buffers have been generated
+ * and are waiting to be swapped with the drawable buffers
+ */
+ private boolean switchVbos = false;
+
+
+ /**
+ * Size of the buffer builders in bytes last time we created them
+ */
+ public int previousBufferSize = 0;
+
+ /**
+ * Width of the dimension in regions last time we created the buffers
+ */
+ public int previousRegionWidth = 0;
+
+ /**
+ * this is used to prevent multiple threads creating, destroying, or using the buffers at the same time
+ */
+ private ReentrantLock bufferLock = new ReentrantLock();
+
+
+ public LodBufferBuilder()
+ {
+
+ }
+
+
+ /**
+ * Create a thread to asynchronously generate LOD buffers
+ * centered around the given camera X and Z.
+ *
+ * May have to wait for the bufferLock to open.
+ */
+ public void setupBuffers(int numbRegionsWide, int bufferMaxCapacity)
+ {
+ bufferLock.lock();
+
+ previousRegionWidth = numbRegionsWide;
+ previousBufferSize = bufferMaxCapacity;
+
+
+ buildableBuffers = new BufferBuilder[numbRegionsWide][numbRegionsWide];
+
+ buildableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide];
+ drawableVbos = new VertexBuffer[numbRegionsWide][numbRegionsWide];
+
+ for (int x = 0; x < numbRegionsWide; x++)
+ {
+ for (int z = 0; z < numbRegionsWide; z++)
+ {
+ buildableBuffers[x][z] = new BufferBuilder(bufferMaxCapacity);
+ buildableVbos[x][z] = new VertexBuffer(LodRenderer.LOD_VERTEX_FORMAT);
+ drawableVbos[x][z] = new VertexBuffer(LodRenderer.LOD_VERTEX_FORMAT);
+ }
+ }
+
+ bufferLock.unlock();
+ }
+
+ /**
+ * sets the buffers and Vbos to null, forcing them to be recreated.
+ * May have to wait for the bufferLock to open.
+ */
+ public void destroyBuffers()
+ {
+ bufferLock.lock();
+
+ buildableBuffers = null;
+ buildableVbos = null;
+ drawableVbos = null;
+
+ bufferLock.unlock();
+ }
+
+
+ /**
+ * Calls begin on each of the buildable BufferBuilders.
+ */
+ private void startBuffers()
+ {
+ for (int x = 0; x < buildableBuffers.length; x++)
+ for (int z = 0; z < buildableBuffers.length; z++)
+ buildableBuffers[x][z].begin(GL11.GL_QUADS, LodRenderer.LOD_VERTEX_FORMAT);
+ }
+
+ /**
+ * Calls end on each of the buildable BufferBuilders.
+ */
+ private void closeBuffers()
+ {
+ for (int x = 0; x < buildableBuffers.length; x++)
+ for (int z = 0; z < buildableBuffers.length; z++)
+ if (buildableBuffers[x][z] != null && buildableBuffers[x][z].building())
+ buildableBuffers[x][z].end();
+ }
+
+ /**
+ * Called from the LodRenderer to create the
+ * BufferBuilders at the right size.
+ */
+ private void uploadBuffers()
+ {
+ for (int x = 0; x < buildableVbos.length; x++)
+ {
+ for (int z = 0; z < buildableVbos.length; z++)
+ {
+ buildableVbos[x][z].upload(buildableBuffers[x][z]);
+ }
+ }
+ }
+
+
+ /**
+ * Get the newly created VBOs
+ */
+ public VertexBuffer[][] getVertexBuffers()
+ {
+ // don't wait for the lock to open
+ // since this is called on the main render thread
+ if (bufferLock.tryLock())
+ {
+ VertexBuffer[][] tmp = drawableVbos;
+ drawableVbos = buildableVbos;
+ buildableVbos = tmp;
+
+ // the vbos have been swapped
+ switchVbos = false;
+ bufferLock.unlock();
+ }
+
+ return drawableVbos;
+ }
+
+ /**
+ * If this is true the buildable near and far
+ * buffers have been generated and are ready to be
+ * sent to the LodRenderer.
+ */
+ public boolean newBuffersAvaliable()
+ {
+ return switchVbos;
+ }
}
diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java
index b75ea7e8e..0ef114ea1 100644
--- a/src/main/java/com/seibel/lod/builders/LodBuilder.java
+++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java
@@ -57,496 +57,500 @@ import net.minecraft.world.gen.Heightmap;
*/
public class LodBuilder
{
- private ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName()));
+ private ExecutorService lodGenThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName()));
- 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;
+ 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;
- /** If no blocks are found in the area in determineBottomPointForArea return this */
- public static final short DEFAULT_DEPTH = -1;
- /** If no blocks are found in the area in determineHeightPointForArea return this */
+ /**
+ * If no blocks are found in the area in determineBottomPointForArea return this
+ */
+ public static final short DEFAULT_DEPTH = -1;
+ /**
+ * If no blocks are found in the area in determineHeightPointForArea return this
+ */
public static final short DEFAULT_HEIGHT = -1;
-
- /**
- * How wide LodDimensions should be in regions
- */
- public int defaultDimensionWidthInRegions = 5;
-
- 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())
- return;
-
- // don't try to create an LOD object
- // if for some reason we aren't
- // given a valid chunk object
- if (chunk == null)
- return;
-
- Thread thread = new Thread(() ->
- {
- try
- {
- DimensionType dim = world.dimensionType();
-
-
- LodDimension lodDim;
-
- if (lodWorld.getLodDimension(dim) == null)
- {
- lodDim = new LodDimension(dim, lodWorld, defaultDimensionWidthInRegions);
- lodWorld.addLodDimension(lodDim);
- } else
- {
- lodDim = lodWorld.getLodDimension(dim);
- }
-
- generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig(generationMode), LodConfig.CLIENT.maxGenerationDetail.get());
- } catch (IllegalArgumentException | NullPointerException e)
- {
- System.out.println("Chunk pos " + chunk.getPos());
- e.printStackTrace();
- // if the world changes while LODs are being generated
- // they will throw errors as they try to access things that no longer
- // exist.
- }
- });
- lodGenThreadPool.execute(thread);
-
- return;
- }
-
- /**
- * Creates a LodChunk for a chunk in the given world.
- *
- * @throws IllegalArgumentException thrown if either the chunk or world is null.
- */
- public void generateLodNodeFromChunk(LodDimension lodDim, IChunk chunk, LodDetail detailLevel) throws IllegalArgumentException
- {
- generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig(), detailLevel);
- }
-
- /**
- * Creates a LodChunk for a chunk in the given world.
- *
- * @throws IllegalArgumentException thrown if either the chunk or world is null.
- */
- public void generateLodNodeFromChunk(LodDimension lodDim, IChunk chunk, LodBuilderConfig config, LodDetail detail)
- throws IllegalArgumentException
- {
-
- if (chunk == null)
- throw new IllegalArgumentException("generateLodFromChunk given a null chunk");
-
- boolean check = false;
-
- int startX;
- int startZ;
- int endX;
- int endZ;
- short[] color;
- short height;
- short depth;
- LevelPos levelPos = new LevelPos((byte) 0, 0, 0);
- short[] data;
- try
- {
- 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(chunk, config, startX, startZ, endX, endZ);
-
- if (!config.useHeightmap)
- {
- height = determineHeightPointForArea(chunk.getSections(), startX, startZ, endX, endZ);
- depth = determineBottomPointForArea(chunk.getSections(), startX, startZ, endX, endZ);
- } else
- {
- height = determineHeightPoint(chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP), startX,
- startZ, endX, endZ);
- depth = 0;
- }
- levelPos.changeParameters((byte) 0,
- chunk.getPos().x * 16 + startX,
- chunk.getPos().z * 16 + startZ);
- levelPos.convert(detail.detailLevel);
- data = DataPoint.createDataPoint(height, depth, color[0], color[1], color[2]);
- lodDim.addData(levelPos,
- data,
- config.distanceGenerationMode,
- false);
- }
- //levelPos.changeParameters(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z);
-
- lodDim.updateData(new LevelPos(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z));
- } catch (NullPointerException e)
- {
- e.printStackTrace();
- } catch (ArrayIndexOutOfBoundsException e)
- {
- e.printStackTrace();
- }
- }
-
-
- // =====================//
- // constructor helpers //
- // =====================//
-
- /**
- * Find the lowest valid point from the bottom.
- */
- private short determineBottomPointForArea(ChunkSection[] chunkSections, int startX, int startZ, int endX, int endZ)
- {
- int numberOfBlocksRequired = ((endX - startX) * (endZ - startZ) / 2);
-
- // search from the bottom up
- for (int section = 0; section < CHUNK_DATA_WIDTH; section++)
- {
- for (int y = 0; y < CHUNK_SECTION_HEIGHT; y++)
- {
- int numberOfBlocksFound = 0;
-
- for (int x = startX; x < endX; x++)
- {
- for (int z = startZ; z < endZ; z++)
- {
- if (isLayerValidLodPoint(chunkSections, section, y, x, z))
- {
- numberOfBlocksFound++;
-
- if (numberOfBlocksFound >= numberOfBlocksRequired)
- {
- // we found
- // enough blocks in this
- // layer to count as an
- // LOD point
- return (short) (y + (section * CHUNK_SECTION_HEIGHT));
- }
- }
- }
- }
- }
- }
-
- // we never found a valid LOD point
- return DEFAULT_DEPTH;
- }
-
-
- /**
- * Find the lowest valid point from the bottom.
- */
- @SuppressWarnings("unused")
- private short determineBottomPoint(Heightmap heightmap)
- {
- // the heightmap only shows how high the blocks go, it
- // doesn't have any info about how low they go
- return 0;
- }
-
- /**
- * Find the highest valid point from the Top
- */
- private short determineHeightPointForArea(ChunkSection[] chunkSections, int startX, int startZ, int endX, int endZ)
- {
- int numberOfBlocksRequired = ((endX - startX) * (endZ - startZ) / 2);
- // search from the top down
- for (int section = chunkSections.length - 1; section >= 0; section--)
- {
- for (int y = CHUNK_DATA_WIDTH - 1; y >= 0; y--)
- {
- int numberOfBlocksFound = 0;
-
- for (int x = startX; x < endX; x++)
- {
- for (int z = startZ; z < endZ; z++)
- {
- if (isLayerValidLodPoint(chunkSections, section, y, x, z))
- {
- numberOfBlocksFound++;
-
- if (numberOfBlocksFound >= numberOfBlocksRequired)
- {
- // we found
- // enough blocks in this
- // layer to count as an
- // LOD point
- return (short) (y + 1 + (section * CHUNK_SECTION_HEIGHT));
- }
- }
- }
- }
- }
- }
-
- // we never found a valid LOD point
- return DEFAULT_HEIGHT;
- }
-
-
- /**
- * Find the highest point from the Top
- */
- private short determineHeightPoint(Heightmap heightmap, int startX, int startZ, int endX, int endZ)
- {
- short highest = 0;
- for (int x = startX; x < endX; x++)
- {
- for (int z = startZ; z < endZ; z++)
- {
- short newHeight = (short) heightmap.getFirstAvailable(x, z);
- if (newHeight > highest)
- highest = newHeight;
- }
- }
-
- return highest;
- }
-
- /**
- * Generate the color for the given chunk using biome water color, foliage
- * color, and grass color.
- *
- * @param config_useSolidBlocksInColorGen
* In order of fastest to slowest.
- *
+ *
* @author James Seibel
* @author Leonardo Amato
* @version 8-7-2021
*/
public enum DistanceGenerationMode
{
- /** Don't generate anything */
+ /**
+ * Don't generate anything
+ */
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
* to generate the color.
- * Doesn't generate height, everything is shown at sea level.
- * Multithreaded - Fastest (2-5 ms) */
+ * Doesn't generate height, everything is shown at sea level.
+ * Multithreaded - Fastest (2-5 ms)
+ */
BIOME_ONLY((byte) 1),
-
+
/**
* Same as BIOME_ONLY, except instead
* of always using sea level as the LOD height
@@ -50,30 +54,38 @@ public enum DistanceGenerationMode
* use predetermined heights to simulate having height data.
*/
BIOME_ONLY_SIMULATE_HEIGHT((byte) 2),
-
- /** Generate the world surface,
+
+ /**
+ * Generate the world surface,
* this does NOT include caves, trees,
- * or structures.
- * Multithreaded - Faster (10-20 ms) */
+ * or structures.
+ * Multithreaded - Faster (10-20 ms)
+ */
SURFACE((byte) 3),
-
- /** Generate everything except structures.
+
+ /**
+ * Generate everything except structures.
* NOTE: This may cause world generation bugs or instability,
* since some features cause concurrentModification exceptions.
- * Multithreaded - Fast (15-20 ms) */
+ * Multithreaded - Fast (15-20 ms)
+ */
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 will also show player made structures if you
- * are adding the mod to a pre-existing world.
- * Singlethreaded - Slow (15-50 ms, with spikes up to 200 ms) */
+ * are adding the mod to a pre-existing world.
+ * Singlethreaded - Slow (15-50 ms, with spikes up to 200 ms)
+ */
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 byte complexity;
-
+
DistanceGenerationMode(byte complexity)
{
this.complexity = complexity;
diff --git a/src/main/java/com/seibel/lod/handlers/LodConfig.java b/src/main/java/com/seibel/lod/handlers/LodConfig.java
index fa9055231..81113197c 100644
--- a/src/main/java/com/seibel/lod/handlers/LodConfig.java
+++ b/src/main/java/com/seibel/lod/handlers/LodConfig.java
@@ -42,281 +42,281 @@ import net.minecraftforge.fml.config.ModConfig;
@Mod.EventBusSubscriber
public class LodConfig
{
- public static class Client
- {
- public ForgeConfigSpec.BooleanValue drawLODs;
+ public static class Client
+ {
+ public ForgeConfigSpec.BooleanValue drawLODs;
- public ForgeConfigSpec.EnumValue
+ * example: "lod.0.0.txt"
+ * Returns null if there is an IO Exception.
+ */
+ private String getFileNameAndPathForRegion(int regionX, int regionZ, byte detailLevel)
+ {
+ try
+ {
+ // saveFolder is something like
+ // ".\Super Flat\DIM-1\data"
+ // or
+ // ".\Super Flat\data"
+ return dimensionDataSaveFolder.getCanonicalPath() + File.separatorChar +
+ DETAIL_FOLDER_NAME_PREFIX + detailLevel + File.separatorChar +
+ FILE_NAME_PREFIX + "." + regionX + "." + regionZ + FILE_EXTENSION;
+ } catch (IOException | SecurityException e)
+ {
+ ClientProxy.LOGGER.warn("Unable to get the filename for the region [" + regionX + ", " + regionZ + "], error: [" + e.getMessage() + "], stacktrace: ");
+ e.printStackTrace();
+ return null;
+ }
+ }
}
diff --git a/src/main/java/com/seibel/lod/handlers/ReflectionHandler.java b/src/main/java/com/seibel/lod/handlers/ReflectionHandler.java
index 386535813..843fd8e8b 100644
--- a/src/main/java/com/seibel/lod/handlers/ReflectionHandler.java
+++ b/src/main/java/com/seibel/lod/handlers/ReflectionHandler.java
@@ -27,7 +27,7 @@ import net.minecraft.client.Minecraft;
* This object is used to get variables from methods
* where they are private. Specifically the fog setting
* in Optifine.
- *
+ *
* @author James Seibel
* @version 7-03-2021
*/
@@ -35,15 +35,13 @@ public class ReflectionHandler
{
private Minecraft mc = Minecraft.getInstance();
public Field ofFogField = null;
-
+
public ReflectionHandler()
{
setupFogField();
}
-
-
-
-
+
+
/**
* Similar to setupFovMethod.
*/
@@ -51,27 +49,24 @@ public class ReflectionHandler
{
// get every variable from the entity renderer
Field[] optionFields = mc.options.getClass().getDeclaredFields();
-
+
// try and find the ofFogType variable in gameSettings
- for(Field field : optionFields)
+ for (Field field : optionFields)
{
- if(field.getName().equals("ofFogType"))
+ if (field.getName().equals("ofFogType"))
{
ofFogField = field;
return;
}
}
-
+
// we didn't find the field,
// either optifine isn't installed, or
// optifine changed the name of the variable
ofFogField = null;
}
-
-
-
-
-
+
+
/**
* Get what type of fog optifine is currently set to render.
*/
@@ -84,25 +79,24 @@ public class ReflectionHandler
// the setup method wasn't called yet.
return FogQuality.FANCY;
}
-
+
int returnNum = 0;
-
+
try
{
- returnNum = (int)ofFogField.get(mc.options);
- }
- catch (IllegalArgumentException | IllegalAccessException e)
+ returnNum = (int) ofFogField.get(mc.options);
+ } catch (IllegalArgumentException | IllegalAccessException e)
{
e.printStackTrace();
}
-
+
switch (returnNum)
{
// optifine's "default" option,
// it should never be called in this case
case 0:
return FogQuality.FAST;
-
+
// normal options
case 1:
return FogQuality.FAST;
@@ -110,10 +104,10 @@ public class ReflectionHandler
return FogQuality.FANCY;
case 3:
return FogQuality.OFF;
-
+
default:
return FogQuality.FAST;
}
}
-
+
}
diff --git a/src/main/java/com/seibel/lod/objects/DataPoint.java b/src/main/java/com/seibel/lod/objects/DataPoint.java
index 1df0e6ae3..3d8d2e6dc 100644
--- a/src/main/java/com/seibel/lod/objects/DataPoint.java
+++ b/src/main/java/com/seibel/lod/objects/DataPoint.java
@@ -3,38 +3,46 @@ package com.seibel.lod.objects;
public class DataPoint
{
- public static short[] createDataPoint(int height, int depth, int red, int green, int blue){
- return new short[]{(short) height, (short) depth, (short) red, (short) green, (short) blue};
- }
+ public static short[] createDataPoint(int height, int depth, int red, int green, int blue)
+ {
+ return new short[]{(short) height, (short) depth, (short) red, (short) green, (short) blue};
+ }
- public static short getHeight(short[] dataPoint){
- return dataPoint[0];
- }
+ public static short getHeight(short[] dataPoint)
+ {
+ return dataPoint[0];
+ }
- public static short getDepth(short[] dataPoint){
- return dataPoint[1];
- }
+ public static short getDepth(short[] dataPoint)
+ {
+ return dataPoint[1];
+ }
- public static short getRed(short[] dataPoint){
- return dataPoint[2];
- }
+ public static short getRed(short[] dataPoint)
+ {
+ return dataPoint[2];
+ }
- public static short getGreen(short[] dataPoint){
- return dataPoint[3];
- }
+ public static short getGreen(short[] dataPoint)
+ {
+ return dataPoint[3];
+ }
- public static short getBlue(short[] dataPoint){
- return dataPoint[4];
- }
+ public static short getBlue(short[] dataPoint)
+ {
+ return dataPoint[4];
+ }
- public static short[] getHeightDepth(short[] dataPoint){
- return new short[]{dataPoint[0], dataPoint[1]};
- }
+ public static short[] getHeightDepth(short[] dataPoint)
+ {
+ return new short[]{dataPoint[0], dataPoint[1]};
+ }
- public static int getColor(short[] dataPoint){
- int R = (dataPoint[2] << 16) & 0x00FF0000;
- int G = (dataPoint[3] << 8) & 0x0000FF00;
- int B = dataPoint[4] & 0x000000FF;
- return 0xFF000000 | R | G | B;
- }
+ public static int getColor(short[] dataPoint)
+ {
+ int R = (dataPoint[2] << 16) & 0x00FF0000;
+ int G = (dataPoint[3] << 8) & 0x0000FF00;
+ int B = dataPoint[4] & 0x000000FF;
+ return 0xFF000000 | R | G | B;
+ }
}
diff --git a/src/main/java/com/seibel/lod/objects/LevelContainer.java b/src/main/java/com/seibel/lod/objects/LevelContainer.java
index 7ca9cdffe..75795b064 100644
--- a/src/main/java/com/seibel/lod/objects/LevelContainer.java
+++ b/src/main/java/com/seibel/lod/objects/LevelContainer.java
@@ -7,104 +7,104 @@ import com.seibel.lod.util.LodUtil;
public class LevelContainer implements Serializable
{
- public static final char DATA_DELIMITER = ',';
+ public static final char DATA_DELIMITER = ',';
- public final byte detailLevel;
+ public final byte detailLevel;
- public final byte[][][] colors;
+ public final byte[][][] colors;
- public final short[][] height;
+ public final short[][] height;
- public final short[][] depth;
+ public final short[][] depth;
- public final byte[][] generationType;
+ public final byte[][] generationType;
- public final boolean[][] dataExistence;
+ public final boolean[][] dataExistence;
- public LevelContainer(byte detailLevel, byte[][][] colors, short[][] height, short[][] depth, byte[][] generationType, boolean[][] dataExistence)
- {
- this.detailLevel = detailLevel;
- this.colors = colors;
- this.height = height;
- this.depth = depth;
- this.generationType = generationType;
- this.dataExistence = dataExistence;
- }
+ public LevelContainer(byte detailLevel, byte[][][] colors, short[][] height, short[][] depth, byte[][] generationType, boolean[][] dataExistence)
+ {
+ this.detailLevel = detailLevel;
+ this.colors = colors;
+ this.height = height;
+ this.depth = depth;
+ this.generationType = generationType;
+ this.dataExistence = dataExistence;
+ }
- public LevelContainer(String data)
- {
+ public LevelContainer(String data)
+ {
- int index = 0;
- int lastIndex = 0;
+ int index = 0;
+ int lastIndex = 0;
- index = data.indexOf(DATA_DELIMITER, 0);
- this.detailLevel = (byte) Integer.parseInt(data.substring(0, index));
- int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
+ index = data.indexOf(DATA_DELIMITER, 0);
+ this.detailLevel = (byte) Integer.parseInt(data.substring(0, index));
+ int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
- this.colors = new byte[size][size][3];
- this.height = new short[size][size];
- this.depth = new short[size][size];
- this.generationType = new byte[size][size];
- this.dataExistence = new boolean[size][size];
- int intCol;
- for (int x = 0; x < size; x++)
- {
- for (int z = 0; z < size; z++)
- {
- lastIndex = index;
- index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
- intCol = Integer.parseInt(data.substring(lastIndex + 1, index), 16);
- colors[x][z][0] = (byte) ((intCol >> 16) - 128);
- colors[x][z][1] = (byte) ((intCol >> 8) - 128);
- colors[x][z][2] = (byte) (intCol - 128);
+ this.colors = new byte[size][size][3];
+ this.height = new short[size][size];
+ this.depth = new short[size][size];
+ this.generationType = new byte[size][size];
+ this.dataExistence = new boolean[size][size];
+ int intCol;
+ for (int x = 0; x < size; x++)
+ {
+ for (int z = 0; z < size; z++)
+ {
+ lastIndex = index;
+ index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
+ intCol = Integer.parseInt(data.substring(lastIndex + 1, index), 16);
+ colors[x][z][0] = (byte) ((intCol >> 16) - 128);
+ colors[x][z][1] = (byte) ((intCol >> 8) - 128);
+ colors[x][z][2] = (byte) (intCol - 128);
- lastIndex = index;
- index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
- height[x][z] = Short.parseShort(data.substring(lastIndex + 1, index), 16);
+ lastIndex = index;
+ index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
+ height[x][z] = Short.parseShort(data.substring(lastIndex + 1, index), 16);
- lastIndex = index;
- index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
- depth[x][z] = Short.parseShort(data.substring(lastIndex + 1, index), 16);
+ lastIndex = index;
+ index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
+ depth[x][z] = Short.parseShort(data.substring(lastIndex + 1, index), 16);
- lastIndex = index;
- index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
- generationType[x][z] = Byte.parseByte(data.substring(lastIndex + 1, index), 16);
+ lastIndex = index;
+ index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
+ generationType[x][z] = Byte.parseByte(data.substring(lastIndex + 1, index), 16);
- lastIndex = index;
- index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
- dataExistence[x][z] = Boolean.parseBoolean(data.substring(lastIndex + 1, index));
- }
- }
+ lastIndex = index;
+ index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
+ dataExistence[x][z] = Boolean.parseBoolean(data.substring(lastIndex + 1, index));
+ }
+ }
- }
+ }
- @Override
- public String toString()
- {
- StringBuilder stringBuilder = new StringBuilder();
- int combinedCol;
- int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
- stringBuilder.append(detailLevel);
- stringBuilder.append(DATA_DELIMITER);
- for (int x = 0; x < size; x++)
- {
- for (int z = 0; z < size; z++)
- {
- //Converting the colors to intColor and then to HEX
- combinedCol = ((colors[x][z][0] + 128) << 16) | ((colors[x][z][1] + 128) << 8) | ((colors[x][z][2] + 128));
- stringBuilder.append(Integer.toHexString(combinedCol));
- stringBuilder.append(DATA_DELIMITER);
- stringBuilder.append(Integer.toHexString(height[x][z] & 0xffff));
- stringBuilder.append(DATA_DELIMITER);
- stringBuilder.append(Integer.toHexString(depth[x][z] & 0xffff));
- stringBuilder.append(DATA_DELIMITER);
- stringBuilder.append(Integer.toHexString(generationType[x][z] & 0xffff));
- stringBuilder.append(DATA_DELIMITER);
- stringBuilder.append(dataExistence[x][z]);
- stringBuilder.append(DATA_DELIMITER);
- }
- }
- return stringBuilder.toString();
- }
+ @Override
+ public String toString()
+ {
+ StringBuilder stringBuilder = new StringBuilder();
+ int combinedCol;
+ int size = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
+ stringBuilder.append(detailLevel);
+ stringBuilder.append(DATA_DELIMITER);
+ for (int x = 0; x < size; x++)
+ {
+ for (int z = 0; z < size; z++)
+ {
+ //Converting the colors to intColor and then to HEX
+ combinedCol = ((colors[x][z][0] + 128) << 16) | ((colors[x][z][1] + 128) << 8) | ((colors[x][z][2] + 128));
+ stringBuilder.append(Integer.toHexString(combinedCol));
+ stringBuilder.append(DATA_DELIMITER);
+ stringBuilder.append(Integer.toHexString(height[x][z] & 0xffff));
+ stringBuilder.append(DATA_DELIMITER);
+ stringBuilder.append(Integer.toHexString(depth[x][z] & 0xffff));
+ stringBuilder.append(DATA_DELIMITER);
+ stringBuilder.append(Integer.toHexString(generationType[x][z] & 0xffff));
+ stringBuilder.append(DATA_DELIMITER);
+ stringBuilder.append(dataExistence[x][z]);
+ stringBuilder.append(DATA_DELIMITER);
+ }
+ }
+ return stringBuilder.toString();
+ }
}
diff --git a/src/main/java/com/seibel/lod/objects/LevelPos/MutableLevelPos.java b/src/main/java/com/seibel/lod/objects/LevelPos/MutableLevelPos.java
index a57d3aef4..324fbb47b 100644
--- a/src/main/java/com/seibel/lod/objects/LevelPos/MutableLevelPos.java
+++ b/src/main/java/com/seibel/lod/objects/LevelPos/MutableLevelPos.java
@@ -4,11 +4,11 @@ import com.seibel.lod.util.LodUtil;
public interface MutableLevelPos
{
- public void convert(byte newDetailLevel);
+ public void convert(byte newDetailLevel);
- public void performRegionModule();
+ public void performRegionModule();
- public void applyOffset(int xOffset, int zOffset);
+ public void applyOffset(int xOffset, int zOffset);
- public void changeParameters(byte newDetailLevel, int newPosX, int newPosZ);
+ public void changeParameters(byte newDetailLevel, int newPosX, int newPosZ);
}
diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java
index 8ba339ae0..344cc4467 100644
--- a/src/main/java/com/seibel/lod/objects/LodDimension.java
+++ b/src/main/java/com/seibel/lod/objects/LodDimension.java
@@ -48,718 +48,718 @@ import net.minecraft.world.server.ServerWorld;
public class LodDimension
{
- public final DimensionType dimension;
-
- /**
- * measured in regions
- */
- private volatile int width;
- /**
- * measured in regions
- */
- private volatile int halfWidth;
-
-
- public volatile LodRegion regions[][];
- public volatile boolean isRegionDirty[][];
-
- private volatile RegionPos center;
- private volatile ChunkPos lastGenChunk;
- private volatile ChunkPos lastCutChunk;
- private LodDimensionFileHandler fileHandler;
- private ExecutorService cutAndGenThreads = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " - cutAndGen"));
-
- /**
- * Creates the dimension centered at (0,0)
- *
- * @param newWidth in regions
- */
- public LodDimension(DimensionType newDimension, LodWorld lodWorld, int newWidth)
- {
- lastCutChunk = null;
- lastGenChunk = null;
- dimension = newDimension;
- width = newWidth;
- halfWidth = (int) Math.floor(width / 2);
- Minecraft mc = Minecraft.getInstance();
- if (newDimension != null && lodWorld != null)
- {
- try
- {
-
- File saveDir;
- if (mc.hasSingleplayerServer())
- {
- // local world
-
- ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(newDimension);
-
- // provider needs a separate variable to prevent
- // the compiler from complaining
- ServerChunkProvider provider = serverWorld.getChunkSource();
- saveDir = new File(provider.dataStorage.dataFolder.getCanonicalFile().getPath() + File.separatorChar + "lod");
- } else
- {
- // connected to server
-
- saveDir = new File(mc.gameDirectory.getCanonicalFile().getPath() +
- File.separatorChar + "lod server data" + File.separatorChar + LodUtil.getDimensionIDFromWorld(mc.level));
- }
-
- fileHandler = new LodDimensionFileHandler(saveDir, this);
- } catch (IOException e)
- {
- // the file handler wasn't able to be created
- // we won't be able to read or write any files
- }
- }
-
-
- regions = new LodRegion[width][width];
- isRegionDirty = new boolean[width][width];
-
- //treeGenerator((int) mc.player.getX(),(int) mc.player.getZ());
-
- // populate isRegionDirty
- for (int i = 0; i < width; i++)
- for (int j = 0; j < width; j++)
- isRegionDirty[i][j] = false;
-
- center = new RegionPos(0, 0);
- }
-
-
- /**
- * Move the center of this LodDimension and move all owned
- * regions over by the given x and z offset.
- * Synchronized to prevent multiple moves happening on top of each other.
- */
- public synchronized void move(RegionPos regionOffset)
- {
- int xOffset = regionOffset.x;
- int zOffset = regionOffset.z;
-
- // if the x or z offset is equal to or greater than
- // the total size, just delete the current data
- // and update the centerX and/or centerZ
- if (Math.abs(xOffset) >= width || Math.abs(zOffset) >= width)
- {
- for (int x = 0; x < width; x++)
- {
- for (int z = 0; z < width; z++)
- {
- regions[x][z] = null;
- }
- }
-
- // update the new center
- center.x += xOffset;
- center.z += zOffset;
-
- return;
- }
-
-
- // X
- if (xOffset > 0)
- {
- // move everything over to the left (as the center moves to the right)
- for (int x = 0; x < width; x++)
- {
- for (int z = 0; z < width; z++)
- {
- if (x + xOffset < width)
- regions[x][z] = regions[x + xOffset][z];
- else
- regions[x][z] = null;
- }
- }
- } else
- {
- // move everything over to the right (as the center moves to the left)
- for (int x = width - 1; x >= 0; x--)
- {
- for (int z = 0; z < width; z++)
- {
- if (x + xOffset >= 0)
- regions[x][z] = regions[x + xOffset][z];
- else
- regions[x][z] = null;
- }
- }
- }
-
-
- // Z
- if (zOffset > 0)
- {
- // move everything up (as the center moves down)
- for (int x = 0; x < width; x++)
- {
- for (int z = 0; z < width; z++)
- {
- if (z + zOffset < width)
- regions[x][z] = regions[x][z + zOffset];
- else
- regions[x][z] = null;
- }
- }
- } else
- {
- // move everything down (as the center moves up)
- for (int x = 0; x < width; x++)
- {
- for (int z = width - 1; z >= 0; z--)
- {
- if (z + zOffset >= 0)
- regions[x][z] = regions[x][z + zOffset];
- else
- regions[x][z] = null;
- }
- }
- }
-
-
- // update the new center
- center.x += xOffset;
- center.z += zOffset;
- }
-
-
- /**
- * return needed memory in byte
- */
- public int getMinMemoryNeeded()
- {
- int regionX;
- int regionZ;
- int count = 0;
- LodRegion region;
-
- for (int x = 0; x < regions.length; x++)
- {
- for (int z = 0; z < regions.length; z++)
- {
- region = regions[x][z];
- if (region != null)
- {
- count += region.getMinMemoryNeeded();
- }
- }
- }
- return count;
- }
-
- /**
- * Gets the region at the given X and Z
- *
+ * Synchronized to prevent multiple moves happening on top of each other.
+ */
+ public synchronized void move(RegionPos regionOffset)
+ {
+ int xOffset = regionOffset.x;
+ int zOffset = regionOffset.z;
+
+ // if the x or z offset is equal to or greater than
+ // the total size, just delete the current data
+ // and update the centerX and/or centerZ
+ if (Math.abs(xOffset) >= width || Math.abs(zOffset) >= width)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ for (int z = 0; z < width; z++)
+ {
+ regions[x][z] = null;
+ }
+ }
+
+ // update the new center
+ center.x += xOffset;
+ center.z += zOffset;
+
+ return;
+ }
+
+
+ // X
+ if (xOffset > 0)
+ {
+ // move everything over to the left (as the center moves to the right)
+ for (int x = 0; x < width; x++)
+ {
+ for (int z = 0; z < width; z++)
+ {
+ if (x + xOffset < width)
+ regions[x][z] = regions[x + xOffset][z];
+ else
+ regions[x][z] = null;
+ }
+ }
+ } else
+ {
+ // move everything over to the right (as the center moves to the left)
+ for (int x = width - 1; x >= 0; x--)
+ {
+ for (int z = 0; z < width; z++)
+ {
+ if (x + xOffset >= 0)
+ regions[x][z] = regions[x + xOffset][z];
+ else
+ regions[x][z] = null;
+ }
+ }
+ }
+
+
+ // Z
+ if (zOffset > 0)
+ {
+ // move everything up (as the center moves down)
+ for (int x = 0; x < width; x++)
+ {
+ for (int z = 0; z < width; z++)
+ {
+ if (z + zOffset < width)
+ regions[x][z] = regions[x][z + zOffset];
+ else
+ regions[x][z] = null;
+ }
+ }
+ } else
+ {
+ // move everything down (as the center moves up)
+ for (int x = 0; x < width; x++)
+ {
+ for (int z = width - 1; z >= 0; z--)
+ {
+ if (z + zOffset >= 0)
+ regions[x][z] = regions[x][z + zOffset];
+ else
+ regions[x][z] = null;
+ }
+ }
+ }
+
+
+ // update the new center
+ center.x += xOffset;
+ center.z += zOffset;
+ }
+
+
+ /**
+ * return needed memory in byte
+ */
+ public int getMinMemoryNeeded()
+ {
+ int regionX;
+ int regionZ;
+ int count = 0;
+ LodRegion region;
+
+ for (int x = 0; x < regions.length; x++)
+ {
+ for (int z = 0; z < regions.length; z++)
+ {
+ region = regions[x][z];
+ if (region != null)
+ {
+ count += region.getMinMemoryNeeded();
+ }
+ }
+ }
+ return count;
+ }
+
+ /**
+ * Gets the region at the given X and Z
+ *
* Sets x and z to 0
*/
public RegionPos()
@@ -44,38 +44,41 @@ public class RegionPos
x = 0;
z = 0;
}
-
+
public RegionPos(int newX, int newZ)
{
x = newX;
z = newZ;
}
-
+
public RegionPos(BlockPos pos)
{
this(new ChunkPos(pos));
}
-
+
public RegionPos(ChunkPos pos)
{
x = Math.floorDiv(pos.x, LodUtil.REGION_WIDTH_IN_CHUNKS);
z = Math.floorDiv(pos.z, LodUtil.REGION_WIDTH_IN_CHUNKS);
}
-
- /** Returns the ChunkPos at the center of this region */
+
+ /**
+ * Returns the ChunkPos at the center of this region
+ */
public ChunkPos chunkPos()
{
- return new ChunkPos((x * LodUtil.REGION_WIDTH_IN_CHUNKS) + LodUtil.REGION_WIDTH_IN_CHUNKS/2, (z * LodUtil.REGION_WIDTH_IN_CHUNKS) + LodUtil.REGION_WIDTH_IN_CHUNKS/2);
+ return new ChunkPos((x * LodUtil.REGION_WIDTH_IN_CHUNKS) + LodUtil.REGION_WIDTH_IN_CHUNKS / 2, (z * LodUtil.REGION_WIDTH_IN_CHUNKS) + LodUtil.REGION_WIDTH_IN_CHUNKS / 2);
}
-
- /** Returns the BlockPos at the center of this region */
+
+ /**
+ * Returns the BlockPos at the center of this region
+ */
public BlockPos blockPos()
{
- return chunkPos().getWorldPosition().offset(LodUtil.CHUNK_WIDTH/2, 0, LodUtil.CHUNK_WIDTH/2);
+ return chunkPos().getWorldPosition().offset(LodUtil.CHUNK_WIDTH / 2, 0, LodUtil.CHUNK_WIDTH / 2);
}
-
-
-
+
+
@Override
public String toString()
{
diff --git a/src/main/java/com/seibel/lod/proxy/ClientProxy.java b/src/main/java/com/seibel/lod/proxy/ClientProxy.java
index 18c1321bf..8809cd937 100644
--- a/src/main/java/com/seibel/lod/proxy/ClientProxy.java
+++ b/src/main/java/com/seibel/lod/proxy/ClientProxy.java
@@ -57,266 +57,266 @@ import net.minecraftforge.eventbus.api.SubscribeEvent;
*/
public class ClientProxy
{
- public static final Logger LOGGER = LogManager.getLogger("LOD");
+ public static final Logger LOGGER = LogManager.getLogger("LOD");
- private static LodWorld lodWorld = new LodWorld();
- private static LodBuilder lodBuilder = new LodBuilder();
- private static LodBufferBuilder lodBufferBuilder = new LodBufferBuilder();
- private static LodRenderer renderer = new LodRenderer(lodBufferBuilder);
- private static LodWorldGenerator lodWorldGenerator = LodWorldGenerator.INSTANCE;
+ private static LodWorld lodWorld = new LodWorld();
+ private static LodBuilder lodBuilder = new LodBuilder();
+ private static LodBufferBuilder lodBufferBuilder = new LodBufferBuilder();
+ private static LodRenderer renderer = new LodRenderer(lodBufferBuilder);
+ private static LodWorldGenerator lodWorldGenerator = LodWorldGenerator.INSTANCE;
- private boolean configOverrideReminderPrinted = false;
+ private boolean configOverrideReminderPrinted = false;
- Minecraft mc = Minecraft.getInstance();
+ Minecraft mc = Minecraft.getInstance();
- /**
- * This is used to determine if the LODs should be regenerated
- */
- public static int previousChunkRenderDistance = 0;
- /**
- * This is used to determine if the LODs should be regenerated
- */
- public static int previousLodRenderDistance = 0;
+ /**
+ * This is used to determine if the LODs should be regenerated
+ */
+ public static int previousChunkRenderDistance = 0;
+ /**
+ * This is used to determine if the LODs should be regenerated
+ */
+ public static int previousLodRenderDistance = 0;
- /**
- * can be set if we want to recalculate variables related
- * to the LOD view distance
- */
- private boolean recalculateWidths = false;
+ /**
+ * can be set if we want to recalculate variables related
+ * to the LOD view distance
+ */
+ private boolean recalculateWidths = false;
- public ClientProxy()
- {
+ public ClientProxy()
+ {
- }
+ }
- //==============//
- // render event //
- //==============//
+ //==============//
+ // render event //
+ //==============//
- /**
- * Do any setup that is required to draw LODs
- * and then tell the LodRenderer to draw.
- */
- public void renderLods(float partialTicks)
- {
- if (mc == null || mc.player == null || !lodWorld.getIsWorldLoaded())
- return;
+ /**
+ * Do any setup that is required to draw LODs
+ * and then tell the LodRenderer to draw.
+ */
+ public void renderLods(float partialTicks)
+ {
+ if (mc == null || mc.player == null || !lodWorld.getIsWorldLoaded())
+ return;
- viewDistanceChangedEvent();
+ viewDistanceChangedEvent();
- LodDimension lodDim = lodWorld.getLodDimension(mc.player.level.dimensionType());
- if (lodDim == null)
- return;
+ LodDimension lodDim = lodWorld.getLodDimension(mc.player.level.dimensionType());
+ if (lodDim == null)
+ return;
- playerMoveEvent(lodDim);
- //System.out.println("memory needed " + lodDim.getMinMemoryNeeded() + " byte");
- //System.out.println(lodDim);
+ playerMoveEvent(lodDim);
+ //System.out.println("memory needed " + lodDim.getMinMemoryNeeded() + " byte");
+ //System.out.println(lodDim);
- lodDim.treeCutter((int) mc.player.getX(), (int) mc.player.getZ());
- lodDim.treeGenerator((int) mc.player.getX(), (int) mc.player.getZ());
+ lodDim.treeCutter((int) mc.player.getX(), (int) mc.player.getZ());
+ lodDim.treeGenerator((int) mc.player.getX(), (int) mc.player.getZ());
- // comment out when creating a release
- applyConfigOverrides();
+ // comment out when creating a release
+ applyConfigOverrides();
- // Note to self:
- // if "unspecified" shows up in the pie chart, it is
- // possibly because the amount of time between sections
- // is too small for the profiler to measure
- IProfiler profiler = mc.getProfiler();
- profiler.pop(); // get out of "terrain"
- profiler.push("LOD");
- renderer.drawLODs(lodDim, partialTicks, mc.getProfiler());
+ // Note to self:
+ // if "unspecified" shows up in the pie chart, it is
+ // possibly because the amount of time between sections
+ // is too small for the profiler to measure
+ IProfiler profiler = mc.getProfiler();
+ profiler.pop(); // get out of "terrain"
+ profiler.push("LOD");
+ renderer.drawLODs(lodDim, partialTicks, mc.getProfiler());
- profiler.pop(); // end LOD
- profiler.push("terrain"); // restart "terrain"
+ profiler.pop(); // end LOD
+ profiler.push("terrain"); // restart "terrain"
- // these can't be set until after the buffers are built (in renderer.drawLODs)
- // otherwise the buffers may be set to the wrong size, or not changed at all
- previousChunkRenderDistance = mc.options.renderDistance;
- previousLodRenderDistance = LodConfig.CLIENT.lodChunkRenderDistance.get();
- }
+ // these can't be set until after the buffers are built (in renderer.drawLODs)
+ // otherwise the buffers may be set to the wrong size, or not changed at all
+ previousChunkRenderDistance = mc.options.renderDistance;
+ previousLodRenderDistance = LodConfig.CLIENT.lodChunkRenderDistance.get();
+ }
- private void applyConfigOverrides()
- {
- // remind the developer(s). that config override is active
- if (!configOverrideReminderPrinted)
- {
- mc.player.sendMessage(new StringTextComponent("Debug settings enabled!"), mc.player.getUUID());
- configOverrideReminderPrinted = true;
- }
+ private void applyConfigOverrides()
+ {
+ // remind the developer(s). that config override is active
+ if (!configOverrideReminderPrinted)
+ {
+ mc.player.sendMessage(new StringTextComponent("Debug settings enabled!"), mc.player.getUUID());
+ configOverrideReminderPrinted = true;
+ }
- // LodConfig.CLIENT.drawLODs.set(true);
- LodConfig.CLIENT.debugMode.set(false);
+ // LodConfig.CLIENT.drawLODs.set(true);
+ LodConfig.CLIENT.debugMode.set(false);
- LodConfig.CLIENT.maxDrawDetail.set(LodDetail.FULL);
- LodConfig.CLIENT.maxGenerationDetail.set(LodDetail.FULL);
+ LodConfig.CLIENT.maxDrawDetail.set(LodDetail.FULL);
+ LodConfig.CLIENT.maxGenerationDetail.set(LodDetail.FULL);
- LodConfig.CLIENT.fogDistance.set(FogDistance.FAR);
- LodConfig.CLIENT.fogDrawOverride.set(FogDrawOverride.ALWAYS_DRAW_FOG_FANCY);
- LodConfig.CLIENT.shadingMode.set(ShadingMode.DARKEN_SIDES);
- LodConfig.CLIENT.brightnessMultiplier.set(1.0);
- LodConfig.CLIENT.saturationMultiplier.set(1.0);
+ LodConfig.CLIENT.fogDistance.set(FogDistance.FAR);
+ LodConfig.CLIENT.fogDrawOverride.set(FogDrawOverride.ALWAYS_DRAW_FOG_FANCY);
+ LodConfig.CLIENT.shadingMode.set(ShadingMode.DARKEN_SIDES);
+ LodConfig.CLIENT.brightnessMultiplier.set(1.0);
+ LodConfig.CLIENT.saturationMultiplier.set(1.0);
- LodConfig.CLIENT.distanceGenerationMode.set(DistanceGenerationMode.SURFACE);
- LodConfig.CLIENT.lodChunkRenderDistance.set(128);
- LodConfig.CLIENT.lodDistanceCalculatorType.set(DistanceCalculatorType.LINEAR);
- LodConfig.CLIENT.lodQuality.set(2);
- LodConfig.CLIENT.allowUnstableFeatureGeneration.set(false);
- LodConfig.CLIENT.numberOfWorldGenerationThreads.set(Runtime.getRuntime().availableProcessors());
+ LodConfig.CLIENT.distanceGenerationMode.set(DistanceGenerationMode.SURFACE);
+ LodConfig.CLIENT.lodChunkRenderDistance.set(128);
+ LodConfig.CLIENT.lodDistanceCalculatorType.set(DistanceCalculatorType.LINEAR);
+ LodConfig.CLIENT.lodQuality.set(2);
+ LodConfig.CLIENT.allowUnstableFeatureGeneration.set(false);
+ LodConfig.CLIENT.numberOfWorldGenerationThreads.set(Runtime.getRuntime().availableProcessors());
- // has to be set in the config file
- // LodConfig.CLIENT.numberOfWorldGenerationThreads.set(16);
- }
+ // has to be set in the config file
+ // LodConfig.CLIENT.numberOfWorldGenerationThreads.set(16);
+ }
- //==============//
- // forge events //
- //==============//
+ //==============//
+ // forge events //
+ //==============//
- @SubscribeEvent
- public void serverTickEvent(TickEvent.ServerTickEvent event)
- {
- if (mc == null || mc.player == null || !lodWorld.getIsWorldLoaded())
- return;
+ @SubscribeEvent
+ public void serverTickEvent(TickEvent.ServerTickEvent event)
+ {
+ if (mc == null || mc.player == null || !lodWorld.getIsWorldLoaded())
+ return;
- LodDimension lodDim = lodWorld.getLodDimension(mc.player.level.dimensionType());
- if (lodDim == null)
- return;
+ LodDimension lodDim = lodWorld.getLodDimension(mc.player.level.dimensionType());
+ if (lodDim == null)
+ return;
- lodWorldGenerator.queueGenerationRequests(lodDim, renderer, lodBuilder);
- }
+ lodWorldGenerator.queueGenerationRequests(lodDim, renderer, lodBuilder);
+ }
- @SubscribeEvent
- public void chunkLoadEvent(ChunkEvent.Load event)
- {
- lodBuilder.generateLodNodeAsync(event.getChunk(), lodWorld, event.getWorld(), DistanceGenerationMode.SERVER);
- }
+ @SubscribeEvent
+ public void chunkLoadEvent(ChunkEvent.Load event)
+ {
+ lodBuilder.generateLodNodeAsync(event.getChunk(), lodWorld, event.getWorld(), DistanceGenerationMode.SERVER);
+ }
- @SubscribeEvent
- public void worldSaveEvent(WorldEvent.Save event)
- {
- if (lodWorld != null)
- lodWorld.saveAllDimensions();
- }
+ @SubscribeEvent
+ public void worldSaveEvent(WorldEvent.Save event)
+ {
+ if (lodWorld != null)
+ lodWorld.saveAllDimensions();
+ }
- @SubscribeEvent
- public void worldLoadEvent(WorldEvent.Load event)
- {
- // the player just loaded a new world/dimension
- lodWorld.selectWorld(LodUtil.getWorldID(event.getWorld()));
- // make sure the correct LODs are being rendered
- // (if this isn't done the previous world's LODs may be drawn)
- renderer.regenerateLODsNextFrame();
- }
+ @SubscribeEvent
+ public void worldLoadEvent(WorldEvent.Load event)
+ {
+ // the player just loaded a new world/dimension
+ lodWorld.selectWorld(LodUtil.getWorldID(event.getWorld()));
+ // make sure the correct LODs are being rendered
+ // (if this isn't done the previous world's LODs may be drawn)
+ renderer.regenerateLODsNextFrame();
+ }
- @SubscribeEvent
- public void worldUnloadEvent(WorldEvent.Unload event)
- {
- // the player just unloaded a world/dimension
+ @SubscribeEvent
+ public void worldUnloadEvent(WorldEvent.Unload event)
+ {
+ // the player just unloaded a world/dimension
- if (mc.getConnection().getLevel() == null)
- {
- // if this isn't done unfinished tasks may be left in the queue
- // preventing new LodChunks form being generated
- LodNodeGenWorker.restartExecuterService();
+ if (mc.getConnection().getLevel() == null)
+ {
+ // if this isn't done unfinished tasks may be left in the queue
+ // preventing new LodChunks form being generated
+ LodNodeGenWorker.restartExecuterService();
- LodWorldGenerator.INSTANCE.numberOfChunksWaitingToGenerate.set(0);
- // the player has disconnected from a server
- lodWorld.deselectWorld();
+ LodWorldGenerator.INSTANCE.numberOfChunksWaitingToGenerate.set(0);
+ // the player has disconnected from a server
+ lodWorld.deselectWorld();
- // hopefully this should reduce issues related to the buffer builder
- // breaking when changing worlds.
- renderer.destroyBuffers();
- recalculateWidths = true;
- }
- }
+ // hopefully this should reduce issues related to the buffer builder
+ // breaking when changing worlds.
+ renderer.destroyBuffers();
+ recalculateWidths = true;
+ }
+ }
- @SubscribeEvent
- public void blockChangeEvent(BlockEvent event)
- {
- if (event.getClass() == BlockEvent.BreakEvent.class ||
- event.getClass() == BlockEvent.EntityPlaceEvent.class ||
- event.getClass() == BlockEvent.EntityMultiPlaceEvent.class ||
- event.getClass() == BlockEvent.FluidPlaceBlockEvent.class ||
- event.getClass() == BlockEvent.PortalSpawnEvent.class)
- {
- // recreate the LOD where the blocks were changed
- lodBuilder.generateLodNodeAsync(event.getWorld().getChunk(event.getPos()), lodWorld, event.getWorld());
- }
- }
+ @SubscribeEvent
+ public void blockChangeEvent(BlockEvent event)
+ {
+ if (event.getClass() == BlockEvent.BreakEvent.class ||
+ event.getClass() == BlockEvent.EntityPlaceEvent.class ||
+ event.getClass() == BlockEvent.EntityMultiPlaceEvent.class ||
+ event.getClass() == BlockEvent.FluidPlaceBlockEvent.class ||
+ event.getClass() == BlockEvent.PortalSpawnEvent.class)
+ {
+ // recreate the LOD where the blocks were changed
+ lodBuilder.generateLodNodeAsync(event.getWorld().getChunk(event.getPos()), lodWorld, event.getWorld());
+ }
+ }
- //==================//
- // frame LOD events //
- //==================//
+ //==================//
+ // frame LOD events //
+ //==================//
- /**
- * Re-centers the given LodDimension if it needs to be.
- */
- private void playerMoveEvent(LodDimension lodDim)
- {
- // make sure the dimension is centered
- RegionPos playerRegionPos = new RegionPos(mc.player.blockPosition());
- RegionPos worldRegionOffset = new RegionPos(playerRegionPos.x - lodDim.getCenterX(), playerRegionPos.z - lodDim.getCenterZ());
- if (worldRegionOffset.x != 0 || worldRegionOffset.z != 0)
- {
- lodWorld.saveAllDimensions();
- lodDim.move(worldRegionOffset);
- LOGGER.info("offset: " + worldRegionOffset.x + "," + worldRegionOffset.z + "\t center: " + lodDim.getCenterX() + "," + lodDim.getCenterZ());
- }
- }
+ /**
+ * Re-centers the given LodDimension if it needs to be.
+ */
+ private void playerMoveEvent(LodDimension lodDim)
+ {
+ // make sure the dimension is centered
+ RegionPos playerRegionPos = new RegionPos(mc.player.blockPosition());
+ RegionPos worldRegionOffset = new RegionPos(playerRegionPos.x - lodDim.getCenterX(), playerRegionPos.z - lodDim.getCenterZ());
+ if (worldRegionOffset.x != 0 || worldRegionOffset.z != 0)
+ {
+ lodWorld.saveAllDimensions();
+ lodDim.move(worldRegionOffset);
+ LOGGER.info("offset: " + worldRegionOffset.x + "," + worldRegionOffset.z + "\t center: " + lodDim.getCenterX() + "," + lodDim.getCenterZ());
+ }
+ }
- /**
- * Re-sizes all LodDimensions if they needs to be.
- */
- private void viewDistanceChangedEvent()
- {
- // calculate how wide the dimension(s) should be in regions
- int chunksWide = LodConfig.CLIENT.lodChunkRenderDistance.get() * 2 + 1;
- int newWidth = (int) Math.ceil(chunksWide / (float) LodUtil.REGION_WIDTH_IN_CHUNKS);
- newWidth = (newWidth % 2 == 0) ? (newWidth += 1) : (newWidth += 2); // make sure we have a odd number of regions
+ /**
+ * Re-sizes all LodDimensions if they needs to be.
+ */
+ private void viewDistanceChangedEvent()
+ {
+ // calculate how wide the dimension(s) should be in regions
+ int chunksWide = LodConfig.CLIENT.lodChunkRenderDistance.get() * 2 + 1;
+ int newWidth = (int) Math.ceil(chunksWide / (float) LodUtil.REGION_WIDTH_IN_CHUNKS);
+ newWidth = (newWidth % 2 == 0) ? (newWidth += 1) : (newWidth += 2); // make sure we have a odd number of regions
- // do the dimensions need to change in size?
- if (lodBuilder.defaultDimensionWidthInRegions != newWidth || recalculateWidths)
- {
- // update the dimensions to fit the new width
- lodWorld.resizeDimensionRegionWidth(newWidth);
- lodBuilder.defaultDimensionWidthInRegions = newWidth;
- renderer.setupBuffers(newWidth);
+ // do the dimensions need to change in size?
+ if (lodBuilder.defaultDimensionWidthInRegions != newWidth || recalculateWidths)
+ {
+ // update the dimensions to fit the new width
+ lodWorld.resizeDimensionRegionWidth(newWidth);
+ lodBuilder.defaultDimensionWidthInRegions = newWidth;
+ renderer.setupBuffers(newWidth);
- recalculateWidths = false;
- //LOGGER.info("new dimension width in regions: " + newWidth + "\t potential: " + newWidth );
- }
- }
+ recalculateWidths = false;
+ //LOGGER.info("new dimension width in regions: " + newWidth + "\t potential: " + newWidth );
+ }
+ }
- //================//
- // public getters //
- //================//
+ //================//
+ // public getters //
+ //================//
- public static LodWorld getLodWorld()
- {
- return lodWorld;
- }
+ public static LodWorld getLodWorld()
+ {
+ return lodWorld;
+ }
- public static LodBuilder getLodBuilder()
- {
- return lodBuilder;
- }
+ public static LodBuilder getLodBuilder()
+ {
+ return lodBuilder;
+ }
- public static LodRenderer getRenderer()
- {
- return renderer;
- }
+ public static LodRenderer getRenderer()
+ {
+ return renderer;
+ }
}
diff --git a/src/main/java/com/seibel/lod/util/ColorUtil.java b/src/main/java/com/seibel/lod/util/ColorUtil.java
index d5d019fd2..00ed96c41 100644
--- a/src/main/java/com/seibel/lod/util/ColorUtil.java
+++ b/src/main/java/com/seibel/lod/util/ColorUtil.java
@@ -4,57 +4,67 @@ import java.awt.*;
public class ColorUtil
{
- public static int rgbToInt(int red, int green, int blue){
- return (0xFF << 24) | (red << 16) | (green << 8) | blue;
- }
+ public static int rgbToInt(int red, int green, int blue)
+ {
+ return (0xFF << 24) | (red << 16) | (green << 8) | blue;
+ }
- public static int rgbToInt( int alpha, int red, int green, int blue){
- return (alpha << 24) | (red << 16) | (green << 8) | blue;
- }
+ public static int rgbToInt(int alpha, int red, int green, int blue)
+ {
+ return (alpha << 24) | (red << 16) | (green << 8) | blue;
+ }
- public static int getAlpha(int color){
- return (color>>24)&0xFF;
- }
+ public static int getAlpha(int color)
+ {
+ return (color >> 24) & 0xFF;
+ }
- public static int getRed(int color){
- return (color>>16)&0xFF;
- }
+ public static int getRed(int color)
+ {
+ return (color >> 16) & 0xFF;
+ }
- public static int getGreen(int color){
- return (color>>8)&0xFF;
- }
+ public static int getGreen(int color)
+ {
+ return (color >> 8) & 0xFF;
+ }
- public static int getBlue(int color){
- return color &0xFF;
- }
+ public static int getBlue(int color)
+ {
+ return color & 0xFF;
+ }
- public static int applyShade(int color, int shade){
- if(shade<0)
- {
- return (getAlpha(color) << 24) | (Math.max(getRed(color) + shade, 0) << 16) | (Math.max(getGreen(color) + shade, 0) << 8) | Math.max(getBlue(color) + shade, 0);
- }else{
- return (getAlpha(color) << 24) | (Math.min(getRed(color) + shade, 255) << 16) | (Math.min(getGreen(color) + shade, 255) << 8) | Math.min(getBlue(color) + shade, 255);
- }
- }
+ public static int applyShade(int color, int shade)
+ {
+ if (shade < 0)
+ {
+ return (getAlpha(color) << 24) | (Math.max(getRed(color) + shade, 0) << 16) | (Math.max(getGreen(color) + shade, 0) << 8) | Math.max(getBlue(color) + shade, 0);
+ } else
+ {
+ return (getAlpha(color) << 24) | (Math.min(getRed(color) + shade, 255) << 16) | (Math.min(getGreen(color) + shade, 255) << 8) | Math.min(getBlue(color) + shade, 255);
+ }
+ }
- public static int applyShade(int color, float shade){
- if(shade<1)
- {
- return (getAlpha(color) << 24) | ((int) Math.max(getRed(color) * shade, 0) << 16) | ((int) Math.max(getGreen(color) * shade, 0) << 8) | (int) Math.max(getBlue(color) * shade, 0);
- }else{
- return (getAlpha(color) << 24) | ((int) Math.min(getRed(color) * shade, 255) << 16) | ((int) Math.min(getGreen(color) * shade, 255) << 8) |(int) Math.min(getBlue(color) * shade, 255);
- }
- }
+ public static int applyShade(int color, float shade)
+ {
+ if (shade < 1)
+ {
+ return (getAlpha(color) << 24) | ((int) Math.max(getRed(color) * shade, 0) << 16) | ((int) Math.max(getGreen(color) * shade, 0) << 8) | (int) Math.max(getBlue(color) * shade, 0);
+ } else
+ {
+ return (getAlpha(color) << 24) | ((int) Math.min(getRed(color) * shade, 255) << 16) | ((int) Math.min(getGreen(color) * shade, 255) << 8) | (int) Math.min(getBlue(color) * shade, 255);
+ }
+ }
- /**
- * Edit the given color as a HSV (Hue Saturation Value) color.
- */
- public static int applySaturationAndBrightnessMultipliers(int color, float saturationMultiplier, float brightnessMultiplier)
- {
- float[] hsv = Color.RGBtoHSB( getRed(color), getGreen(color), getBlue(color), null);
- return Color.getHSBColor(
- hsv[0], // hue
- LodUtil.clamp(0.0f, hsv[1] * saturationMultiplier, 1.0f),
- LodUtil.clamp(0.0f, hsv[2] * brightnessMultiplier, 1.0f)).getRGB();
- }
+ /**
+ * Edit the given color as a HSV (Hue Saturation Value) color.
+ */
+ public static int applySaturationAndBrightnessMultipliers(int color, float saturationMultiplier, float brightnessMultiplier)
+ {
+ float[] hsv = Color.RGBtoHSB(getRed(color), getGreen(color), getBlue(color), null);
+ return Color.getHSBColor(
+ hsv[0], // hue
+ LodUtil.clamp(0.0f, hsv[1] * saturationMultiplier, 1.0f),
+ LodUtil.clamp(0.0f, hsv[2] * brightnessMultiplier, 1.0f)).getRGB();
+ }
}
diff --git a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java
index 5e08f43a0..a94405331 100644
--- a/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java
+++ b/src/main/java/com/seibel/lod/util/DetailDistanceUtil.java
@@ -7,26 +7,26 @@ import net.minecraft.client.Minecraft;
public class DetailDistanceUtil
{
- private static double genMultiplier = 1.25;
- private static double treeGenMultiplier = 1.5;
- private static double treeCutMultiplier = 1.25;
- private static int minDetail = LodConfig.CLIENT.maxGenerationDetail.get().detailLevel;
- private static int maxDetail = LodUtil.REGION_DETAIL_LEVEL + 1;
- private static int minDistance = 0;
- private static int maxDistance = LodConfig.CLIENT.lodChunkRenderDistance.get() * 16;
+ private static double genMultiplier = 1.25;
+ private static double treeGenMultiplier = 1.5;
+ private static double treeCutMultiplier = 1.25;
+ private static int minDetail = LodConfig.CLIENT.maxGenerationDetail.get().detailLevel;
+ private static int maxDetail = LodUtil.REGION_DETAIL_LEVEL + 1;
+ private static int minDistance = 0;
+ private static int maxDistance = LodConfig.CLIENT.lodChunkRenderDistance.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};
+ private static DistanceGenerationMode[] distancesGenerators = {
+ DistanceGenerationMode.SURFACE,
+ DistanceGenerationMode.SURFACE,
+ DistanceGenerationMode.SURFACE,
+ DistanceGenerationMode.SURFACE,
+ DistanceGenerationMode.SURFACE,
+ DistanceGenerationMode.SURFACE,
+ DistanceGenerationMode.SURFACE,
+ DistanceGenerationMode.SURFACE,
+ DistanceGenerationMode.SURFACE,
+ DistanceGenerationMode.SURFACE};
/*private static DistanceGenerationMode[] distancesGenerators = {
DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT,
@@ -40,113 +40,114 @@ public class DetailDistanceUtil
DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT,
DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT};*/
- private static LodDetail[] lodDetails = {
- LodDetail.FULL,
- LodDetail.HALF,
- LodDetail.QUAD,
- LodDetail.DOUBLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE};
+ private static LodDetail[] lodDetails = {
+ LodDetail.FULL,
+ LodDetail.HALF,
+ LodDetail.QUAD,
+ LodDetail.DOUBLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE};
- private static LodDetail[] lodDetailsCut = {
- LodDetail.FULL,
- LodDetail.HALF,
- LodDetail.QUAD,
- LodDetail.DOUBLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE,
- LodDetail.SINGLE};
+ private static LodDetail[] lodDetailsCut = {
+ LodDetail.FULL,
+ LodDetail.HALF,
+ LodDetail.QUAD,
+ LodDetail.DOUBLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE,
+ LodDetail.SINGLE};
- public static int getDistanceRendering(int detail)
- {
- int initial;
- int distance = 0;
- if(detail <= minDetail)
- return minDistance;
- if(detail == maxDetail)
- return maxDistance*2;
- if(detail == maxDetail+1)
- return maxDistance*3;
- switch (LodConfig.CLIENT.lodDistanceCalculatorType.get())
- {
- case LINEAR:
- initial = LodConfig.CLIENT.lodQuality.get() * 128;
- return (detail * initial);
- case QUADRATIC:
- initial = LodConfig.CLIENT.lodQuality.get() * 128;
- return (int) (Math.pow(2, detail) * initial);
- case RENDER_DEPENDANT:
- int realRenderDistance = Minecraft.getInstance().options.renderDistance * 16;
- int border = 64;
- byte detailAtBorder = (byte) 4;
- if(detail > detailAtBorder){
- return (detail * (border-realRenderDistance)/detailAtBorder + realRenderDistance);
- }else{
- return ((maxDetail - detail) * (maxDistance-border)/(maxDetail - detailAtBorder) + border);
- }
- }
- return distance;
- }
+ public static int getDistanceRendering(int detail)
+ {
+ int initial;
+ int distance = 0;
+ if (detail <= minDetail)
+ return minDistance;
+ if (detail == maxDetail)
+ return maxDistance * 2;
+ if (detail == maxDetail + 1)
+ return maxDistance * 3;
+ switch (LodConfig.CLIENT.lodDistanceCalculatorType.get())
+ {
+ case LINEAR:
+ initial = LodConfig.CLIENT.lodQuality.get() * 128;
+ return (detail * initial);
+ case QUADRATIC:
+ initial = LodConfig.CLIENT.lodQuality.get() * 128;
+ return (int) (Math.pow(2, detail) * initial);
+ case RENDER_DEPENDANT:
+ int realRenderDistance = Minecraft.getInstance().options.renderDistance * 16;
+ int border = 64;
+ byte detailAtBorder = (byte) 4;
+ if (detail > detailAtBorder)
+ {
+ return (detail * (border - realRenderDistance) / detailAtBorder + realRenderDistance);
+ } else
+ {
+ return ((maxDetail - detail) * (maxDistance - border) / (maxDetail - detailAtBorder) + border);
+ }
+ }
+ return distance;
+ }
- public static int getDistanceGeneration(int detail)
- {
- if(detail == maxDetail)
- return maxDistance;
- return (int) (getDistanceRendering(detail) * genMultiplier);
- }
- public static int getDistanceTreeCut(int detail)
- {
- if(detail == maxDetail)
- return maxDistance;
- return (int) (getDistanceRendering(detail) * treeCutMultiplier);
- }
- public static int getDistanceTreeGen(int detail)
- {
- if(detail == maxDetail)
- return maxDistance;
- return (int) (getDistanceRendering(detail) * treeGenMultiplier);
- }
+ public static int getDistanceGeneration(int detail)
+ {
+ if (detail == maxDetail)
+ return maxDistance;
+ return (int) (getDistanceRendering(detail) * genMultiplier);
+ }
- public static DistanceGenerationMode getDistanceGenerationMode(int detail)
- {
- return distancesGenerators[detail];
- }
+ public static int getDistanceTreeCut(int detail)
+ {
+ if (detail == maxDetail)
+ return maxDistance;
+ return (int) (getDistanceRendering(detail) * treeCutMultiplier);
+ }
- public static LodDetail getLodDetail(int detail)
- {
- if(detail < minDetail)
- {
- return lodDetails[minDetail];
- }
- else
- {
- return lodDetails[detail];
- }
- }
+ public static int getDistanceTreeGen(int detail)
+ {
+ if (detail == maxDetail)
+ return maxDistance;
+ return (int) (getDistanceRendering(detail) * treeGenMultiplier);
+ }
+
+ public static DistanceGenerationMode getDistanceGenerationMode(int detail)
+ {
+ return distancesGenerators[detail];
+ }
+
+ public static LodDetail getLodDetail(int detail)
+ {
+ if (detail < minDetail)
+ {
+ return lodDetails[minDetail];
+ } else
+ {
+ return lodDetails[detail];
+ }
+ }
- public static byte getCutLodDetail(int detail)
- {
- if(detail < minDetail)
- {
- return lodDetailsCut[minDetail].detailLevel;
- }
- else if(detail == maxDetail)
- {
- return LodUtil.REGION_DETAIL_LEVEL;
- }
- else
- {
- return lodDetailsCut[detail].detailLevel;
- }
- }
+ public static byte getCutLodDetail(int detail)
+ {
+ if (detail < minDetail)
+ {
+ return lodDetailsCut[minDetail].detailLevel;
+ } else if (detail == maxDetail)
+ {
+ return LodUtil.REGION_DETAIL_LEVEL;
+ } else
+ {
+ return lodDetailsCut[detail].detailLevel;
+ }
+ }
}
+ * This method will write to the drawable near and far buffers.
+ *
+ * After the buildable buffers have been generated they must be
+ * swapped with the drawable buffers in the LodRenderer to be drawn.
+ */
+ public void generateLodBuffersAsync(LodRenderer renderer, LodDimension lodDim,
+ BlockPos playerBlockPos, int numbChunksWide)
+ {
+ // only allow one generation process to happen at a time
+ if (generatingBuffers)
+ return;
+
+ if (buildableBuffers == null)
+ throw new IllegalStateException("\"generateLodBuffersAsync\" was called before the \"setupBuffers\" method was called.");
+
+
+ generatingBuffers = true;
+
+
+ // round the player's block position down to the nearest chunk BlockPos
+ ChunkPos playerChunkPos = new ChunkPos(playerBlockPos);
+ BlockPos playerBlockPosRounded = playerChunkPos.getWorldPosition();
+
+
+ Thread thread = new Thread(() ->
+ {
+ bufferLock.lock();
+
+
+ try
+ {
+ long treeStart = System.currentTimeMillis();
+ long treeEnd = System.currentTimeMillis();
+
+ long startTime = System.currentTimeMillis();
+
+
+ ArrayList
+ *
+ *
- * If true we look down from the top of
- * the
- * chunk until we find a non-invisible
- * block, and then use
- * its color. If false we generate the
- * color immediately for
- * each x and z.
- * @param config_useBiomeColors
- * If true use biome foliage, water, and
- * grass colors,
- * otherwise only use the block's
- * material color
- */
- private short[] generateLodColorForArea(IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX,
- int endZ)
- {
- ChunkSection[] chunkSections = chunk.getSections();
-
- 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++)
- {
- boolean foundBlock = false;
-
- // go top down
- for (int i = chunkSections.length - 1; !foundBlock && i >= 0; i--)
- {
- if (!foundBlock && (chunkSections[i] != null || !config.useSolidBlocksInColorGen))
- {
- for (int y = CHUNK_SECTION_HEIGHT - 1; !foundBlock && y >= 0; y--)
- {
- int colorInt = 0;
- BlockState blockState = null;
-
- if (chunkSections[i] != null)
- {
- blockState = chunkSections[i].getBlockState(x, y, z);
- colorInt = blockState.materialColor.col;
- }
-
- if (colorInt == 0 && config.useSolidBlocksInColorGen)
- {
- // skip air or invisible blocks
- continue;
- }
-
- if (config.useBiomeColors)
- {
- // I have no idea why I need to bit shift to the right, but
- // if I don't the biomes don't show up correctly.
- Biome biome = chunk.getBiomes().getNoiseBiome(x >> 2, y + 1 * chunkSections.length >> 2,
- z >> 2);
- colorInt = getColorForBiome(x, z, biome);
- } else
- {
-
- // the bit shift is equivalent to dividing by 4
- Biome biome = chunk.getBiomes().getNoiseBiome(x >> 2, y + i * chunkSections.length >> 2,
- z >> 2);
- colorInt = getColorForBlock(x, z, blockState, biome);
- }
-
- red += ColorUtil.getRed(colorInt);
- green += ColorUtil.getGreen(colorInt);
- blue += ColorUtil.getBlue(colorInt);
-
- numbOfBlocks++;
-
- // we found a valid block, skip to the
- // next x and z
- foundBlock = true;
- }
- }
- }
- }
- }
-
- if (numbOfBlocks == 0)
- numbOfBlocks = 1;
-
- red /= numbOfBlocks;
- green /= numbOfBlocks;
- blue /= numbOfBlocks;
-
- return new short[]{(short) red, (short) green, (short) blue};
- }
-
- /**
- * Returns a color int for a given block.
- */
- private int getColorForBlock(int x, int z, BlockState blockState, Biome biome)
- {
- int colorInt = 0;
-
- // block special cases
- if (blockState == Blocks.AIR.defaultBlockState() || blockState == Blocks.CAVE_AIR.defaultBlockState())
- {
- Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z));
- tmp = tmp.darker();
- colorInt = LodUtil.colorToInt(tmp);
- } else if (blockState == Blocks.MYCELIUM.defaultBlockState())
- {
- colorInt = LodUtil.MYCELIUM_COLOR_INT;
- }
-
- // plant life
- else if (blockState.getBlock() instanceof LeavesBlock || blockState.getBlock() == Blocks.VINE)
- {
- Color leafColor = LodUtil.intToColor(biome.getFoliageColor()).darker();
- leafColor = leafColor.darker();
- colorInt = LodUtil.colorToInt(leafColor);
- } else if ((blockState.getBlock() instanceof GrassBlock || blockState.getBlock() instanceof AbstractPlantBlock
- || blockState.getBlock() instanceof BushBlock || blockState.getBlock() instanceof IGrowable)
- && !(blockState.getBlock() == Blocks.BROWN_MUSHROOM || blockState.getBlock() == Blocks.RED_MUSHROOM))
- {
- Color plantColor = LodUtil.intToColor(biome.getGrassColor(x, z));
- plantColor = plantColor.darker();
- colorInt = LodUtil.colorToInt(plantColor);
- }
-
- // water
- else if (blockState.getBlock() == Blocks.WATER)
- {
- colorInt = biome.getWaterColor();
- }
-
- // everything else
- else
- {
- colorInt = blockState.materialColor.col;
- }
-
- return colorInt;
- }
-
- /**
- * Returns a color int for the given biome.
- */
- private int getColorForBiome(int x, int z, Biome biome)
- {
- int colorInt = 0;
-
- switch (biome.getBiomeCategory())
- {
-
- case NETHER:
- colorInt = Blocks.BEDROCK.defaultBlockState().materialColor.col;
- break;
-
- case THEEND:
- colorInt = Blocks.END_STONE.defaultBlockState().materialColor.col;
- break;
-
- case BEACH:
- case DESERT:
- colorInt = Blocks.SAND.defaultBlockState().materialColor.col;
- break;
-
- case EXTREME_HILLS:
- colorInt = Blocks.STONE.defaultMaterialColor().col;
- break;
-
- case MUSHROOM:
- colorInt = MaterialColor.COLOR_LIGHT_GRAY.col;
- break;
-
- case ICY:
- colorInt = Blocks.SNOW.defaultMaterialColor().col;
- break;
-
- case MESA:
- colorInt = Blocks.RED_SAND.defaultMaterialColor().col;
- break;
-
- case OCEAN:
- case RIVER:
- colorInt = biome.getWaterColor();
- break;
-
- case NONE:
- case FOREST:
- case TAIGA:
- case JUNGLE:
- case PLAINS:
- case SAVANNA:
- case SWAMP:
- default:
- Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z));
- tmp = tmp.darker();
- colorInt = LodUtil.colorToInt(tmp);
- break;
-
- }
-
- return colorInt;
- }
-
- /**
- * Is the layer between the given X, Z, and dataIndex values a valid LOD point?
- */
- private boolean isLayerValidLodPoint(ChunkSection[] chunkSections, int sectionIndex, int y, int x, int z)
- {
- if (chunkSections[sectionIndex] == null)
- {
- // this section doesn't have any blocks,
- // it is not a valid section
- return false;
- } else
- {
- if (chunkSections[sectionIndex].getBlockState(x, y, z) != null
- && chunkSections[sectionIndex].getBlockState(x, y, z).getBlock() != Blocks.AIR
- && chunkSections[sectionIndex].getBlockState(x, y, z).getBlock() != Blocks.CAVE_AIR)
- {
- return true;
- }
- }
-
- return false;
- }
+
+ /**
+ * How wide LodDimensions should be in regions
+ */
+ public int defaultDimensionWidthInRegions = 5;
+
+ 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())
+ return;
+
+ // don't try to create an LOD object
+ // if for some reason we aren't
+ // given a valid chunk object
+ if (chunk == null)
+ return;
+
+ Thread thread = new Thread(() ->
+ {
+ try
+ {
+ DimensionType dim = world.dimensionType();
+
+
+ LodDimension lodDim;
+
+ if (lodWorld.getLodDimension(dim) == null)
+ {
+ lodDim = new LodDimension(dim, lodWorld, defaultDimensionWidthInRegions);
+ lodWorld.addLodDimension(lodDim);
+ } else
+ {
+ lodDim = lodWorld.getLodDimension(dim);
+ }
+
+ generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig(generationMode), LodConfig.CLIENT.maxGenerationDetail.get());
+ } catch (IllegalArgumentException | NullPointerException e)
+ {
+ System.out.println("Chunk pos " + chunk.getPos());
+ e.printStackTrace();
+ // if the world changes while LODs are being generated
+ // they will throw errors as they try to access things that no longer
+ // exist.
+ }
+ });
+ lodGenThreadPool.execute(thread);
+
+ return;
+ }
+
+ /**
+ * Creates a LodChunk for a chunk in the given world.
+ *
+ * @throws IllegalArgumentException thrown if either the chunk or world is null.
+ */
+ public void generateLodNodeFromChunk(LodDimension lodDim, IChunk chunk, LodDetail detailLevel) throws IllegalArgumentException
+ {
+ generateLodNodeFromChunk(lodDim, chunk, new LodBuilderConfig(), detailLevel);
+ }
+
+ /**
+ * Creates a LodChunk for a chunk in the given world.
+ *
+ * @throws IllegalArgumentException thrown if either the chunk or world is null.
+ */
+ public void generateLodNodeFromChunk(LodDimension lodDim, IChunk chunk, LodBuilderConfig config, LodDetail detail)
+ throws IllegalArgumentException
+ {
+
+ if (chunk == null)
+ throw new IllegalArgumentException("generateLodFromChunk given a null chunk");
+
+ boolean check = false;
+
+ int startX;
+ int startZ;
+ int endX;
+ int endZ;
+ short[] color;
+ short height;
+ short depth;
+ LevelPos levelPos = new LevelPos((byte) 0, 0, 0);
+ short[] data;
+ try
+ {
+ 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(chunk, config, startX, startZ, endX, endZ);
+
+ if (!config.useHeightmap)
+ {
+ height = determineHeightPointForArea(chunk.getSections(), startX, startZ, endX, endZ);
+ depth = determineBottomPointForArea(chunk.getSections(), startX, startZ, endX, endZ);
+ } else
+ {
+ height = determineHeightPoint(chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP), startX,
+ startZ, endX, endZ);
+ depth = 0;
+ }
+ levelPos.changeParameters((byte) 0,
+ chunk.getPos().x * 16 + startX,
+ chunk.getPos().z * 16 + startZ);
+ levelPos.convert(detail.detailLevel);
+ data = DataPoint.createDataPoint(height, depth, color[0], color[1], color[2]);
+ lodDim.addData(levelPos,
+ data,
+ config.distanceGenerationMode,
+ false);
+ }
+ //levelPos.changeParameters(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z);
+
+ lodDim.updateData(new LevelPos(LodUtil.CHUNK_DETAIL_LEVEL, chunk.getPos().x, chunk.getPos().z));
+ } catch (NullPointerException e)
+ {
+ e.printStackTrace();
+ } catch (ArrayIndexOutOfBoundsException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+
+ // =====================//
+ // constructor helpers //
+ // =====================//
+
+ /**
+ * Find the lowest valid point from the bottom.
+ */
+ private short determineBottomPointForArea(ChunkSection[] chunkSections, int startX, int startZ, int endX, int endZ)
+ {
+ int numberOfBlocksRequired = ((endX - startX) * (endZ - startZ) / 2);
+
+ // search from the bottom up
+ for (int section = 0; section < CHUNK_DATA_WIDTH; section++)
+ {
+ for (int y = 0; y < CHUNK_SECTION_HEIGHT; y++)
+ {
+ int numberOfBlocksFound = 0;
+
+ for (int x = startX; x < endX; x++)
+ {
+ for (int z = startZ; z < endZ; z++)
+ {
+ if (isLayerValidLodPoint(chunkSections, section, y, x, z))
+ {
+ numberOfBlocksFound++;
+
+ if (numberOfBlocksFound >= numberOfBlocksRequired)
+ {
+ // we found
+ // enough blocks in this
+ // layer to count as an
+ // LOD point
+ return (short) (y + (section * CHUNK_SECTION_HEIGHT));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // we never found a valid LOD point
+ return DEFAULT_DEPTH;
+ }
+
+
+ /**
+ * Find the lowest valid point from the bottom.
+ */
+ @SuppressWarnings("unused")
+ private short determineBottomPoint(Heightmap heightmap)
+ {
+ // the heightmap only shows how high the blocks go, it
+ // doesn't have any info about how low they go
+ return 0;
+ }
+
+ /**
+ * Find the highest valid point from the Top
+ */
+ private short determineHeightPointForArea(ChunkSection[] chunkSections, int startX, int startZ, int endX, int endZ)
+ {
+ int numberOfBlocksRequired = ((endX - startX) * (endZ - startZ) / 2);
+ // search from the top down
+ for (int section = chunkSections.length - 1; section >= 0; section--)
+ {
+ for (int y = CHUNK_DATA_WIDTH - 1; y >= 0; y--)
+ {
+ int numberOfBlocksFound = 0;
+
+ for (int x = startX; x < endX; x++)
+ {
+ for (int z = startZ; z < endZ; z++)
+ {
+ if (isLayerValidLodPoint(chunkSections, section, y, x, z))
+ {
+ numberOfBlocksFound++;
+
+ if (numberOfBlocksFound >= numberOfBlocksRequired)
+ {
+ // we found
+ // enough blocks in this
+ // layer to count as an
+ // LOD point
+ return (short) (y + 1 + (section * CHUNK_SECTION_HEIGHT));
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // we never found a valid LOD point
+ return DEFAULT_HEIGHT;
+ }
+
+
+ /**
+ * Find the highest point from the Top
+ */
+ private short determineHeightPoint(Heightmap heightmap, int startX, int startZ, int endX, int endZ)
+ {
+ short highest = 0;
+ for (int x = startX; x < endX; x++)
+ {
+ for (int z = startZ; z < endZ; z++)
+ {
+ short newHeight = (short) heightmap.getFirstAvailable(x, z);
+ if (newHeight > highest)
+ highest = newHeight;
+ }
+ }
+
+ return highest;
+ }
+
+ /**
+ * Generate the color for the given chunk using biome water color, foliage
+ * color, and grass color.
+ *
+ * @param config_useSolidBlocksInColorGen
+ * If true we look down from the top of
+ * the
+ * chunk until we find a non-invisible
+ * block, and then use
+ * its color. If false we generate the
+ * color immediately for
+ * each x and z.
+ * @param config_useBiomeColors
+ * If true use biome foliage, water, and
+ * grass colors,
+ * otherwise only use the block's
+ * material color
+ */
+ private short[] generateLodColorForArea(IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX,
+ int endZ)
+ {
+ ChunkSection[] chunkSections = chunk.getSections();
+
+ 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++)
+ {
+ boolean foundBlock = false;
+
+ // go top down
+ for (int i = chunkSections.length - 1; !foundBlock && i >= 0; i--)
+ {
+ if (!foundBlock && (chunkSections[i] != null || !config.useSolidBlocksInColorGen))
+ {
+ for (int y = CHUNK_SECTION_HEIGHT - 1; !foundBlock && y >= 0; y--)
+ {
+ int colorInt = 0;
+ BlockState blockState = null;
+
+ if (chunkSections[i] != null)
+ {
+ blockState = chunkSections[i].getBlockState(x, y, z);
+ colorInt = blockState.materialColor.col;
+ }
+
+ if (colorInt == 0 && config.useSolidBlocksInColorGen)
+ {
+ // skip air or invisible blocks
+ continue;
+ }
+
+ if (config.useBiomeColors)
+ {
+ // I have no idea why I need to bit shift to the right, but
+ // if I don't the biomes don't show up correctly.
+ Biome biome = chunk.getBiomes().getNoiseBiome(x >> 2, y + 1 * chunkSections.length >> 2,
+ z >> 2);
+ colorInt = getColorForBiome(x, z, biome);
+ } else
+ {
+
+ // the bit shift is equivalent to dividing by 4
+ Biome biome = chunk.getBiomes().getNoiseBiome(x >> 2, y + i * chunkSections.length >> 2,
+ z >> 2);
+ colorInt = getColorForBlock(x, z, blockState, biome);
+ }
+
+ red += ColorUtil.getRed(colorInt);
+ green += ColorUtil.getGreen(colorInt);
+ blue += ColorUtil.getBlue(colorInt);
+
+ numbOfBlocks++;
+
+ // we found a valid block, skip to the
+ // next x and z
+ foundBlock = true;
+ }
+ }
+ }
+ }
+ }
+
+ if (numbOfBlocks == 0)
+ numbOfBlocks = 1;
+
+ red /= numbOfBlocks;
+ green /= numbOfBlocks;
+ blue /= numbOfBlocks;
+
+ return new short[]{(short) red, (short) green, (short) blue};
+ }
+
+ /**
+ * Returns a color int for a given block.
+ */
+ private int getColorForBlock(int x, int z, BlockState blockState, Biome biome)
+ {
+ int colorInt = 0;
+
+ // block special cases
+ if (blockState == Blocks.AIR.defaultBlockState() || blockState == Blocks.CAVE_AIR.defaultBlockState())
+ {
+ Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z));
+ tmp = tmp.darker();
+ colorInt = LodUtil.colorToInt(tmp);
+ } else if (blockState == Blocks.MYCELIUM.defaultBlockState())
+ {
+ colorInt = LodUtil.MYCELIUM_COLOR_INT;
+ }
+
+ // plant life
+ else if (blockState.getBlock() instanceof LeavesBlock || blockState.getBlock() == Blocks.VINE)
+ {
+ Color leafColor = LodUtil.intToColor(biome.getFoliageColor()).darker();
+ leafColor = leafColor.darker();
+ colorInt = LodUtil.colorToInt(leafColor);
+ } else if ((blockState.getBlock() instanceof GrassBlock || blockState.getBlock() instanceof AbstractPlantBlock
+ || blockState.getBlock() instanceof BushBlock || blockState.getBlock() instanceof IGrowable)
+ && !(blockState.getBlock() == Blocks.BROWN_MUSHROOM || blockState.getBlock() == Blocks.RED_MUSHROOM))
+ {
+ Color plantColor = LodUtil.intToColor(biome.getGrassColor(x, z));
+ plantColor = plantColor.darker();
+ colorInt = LodUtil.colorToInt(plantColor);
+ }
+
+ // water
+ else if (blockState.getBlock() == Blocks.WATER)
+ {
+ colorInt = biome.getWaterColor();
+ }
+
+ // everything else
+ else
+ {
+ colorInt = blockState.materialColor.col;
+ }
+
+ return colorInt;
+ }
+
+ /**
+ * Returns a color int for the given biome.
+ */
+ private int getColorForBiome(int x, int z, Biome biome)
+ {
+ int colorInt = 0;
+
+ switch (biome.getBiomeCategory())
+ {
+
+ case NETHER:
+ colorInt = Blocks.BEDROCK.defaultBlockState().materialColor.col;
+ break;
+
+ case THEEND:
+ colorInt = Blocks.END_STONE.defaultBlockState().materialColor.col;
+ break;
+
+ case BEACH:
+ case DESERT:
+ colorInt = Blocks.SAND.defaultBlockState().materialColor.col;
+ break;
+
+ case EXTREME_HILLS:
+ colorInt = Blocks.STONE.defaultMaterialColor().col;
+ break;
+
+ case MUSHROOM:
+ colorInt = MaterialColor.COLOR_LIGHT_GRAY.col;
+ break;
+
+ case ICY:
+ colorInt = Blocks.SNOW.defaultMaterialColor().col;
+ break;
+
+ case MESA:
+ colorInt = Blocks.RED_SAND.defaultMaterialColor().col;
+ break;
+
+ case OCEAN:
+ case RIVER:
+ colorInt = biome.getWaterColor();
+ break;
+
+ case NONE:
+ case FOREST:
+ case TAIGA:
+ case JUNGLE:
+ case PLAINS:
+ case SAVANNA:
+ case SWAMP:
+ default:
+ Color tmp = LodUtil.intToColor(biome.getGrassColor(x, z));
+ tmp = tmp.darker();
+ colorInt = LodUtil.colorToInt(tmp);
+ break;
+
+ }
+
+ return colorInt;
+ }
+
+ /**
+ * Is the layer between the given X, Z, and dataIndex values a valid LOD point?
+ */
+ private boolean isLayerValidLodPoint(ChunkSection[] chunkSections, int sectionIndex, int y, int x, int z)
+ {
+ if (chunkSections[sectionIndex] == null)
+ {
+ // this section doesn't have any blocks,
+ // it is not a valid section
+ return false;
+ } else
+ {
+ if (chunkSections[sectionIndex].getBlockState(x, y, z) != null
+ && chunkSections[sectionIndex].getBlockState(x, y, z).getBlock() != Blocks.AIR
+ && chunkSections[sectionIndex].getBlockState(x, y, z).getBlock() != Blocks.CAVE_AIR)
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/src/main/java/com/seibel/lod/builders/LodBuilderConfig.java b/src/main/java/com/seibel/lod/builders/LodBuilderConfig.java
index 2fd48ee31..60454948a 100644
--- a/src/main/java/com/seibel/lod/builders/LodBuilderConfig.java
+++ b/src/main/java/com/seibel/lod/builders/LodBuilderConfig.java
@@ -30,83 +30,83 @@ import com.seibel.lod.enums.DistanceGenerationMode;
*/
public class LodBuilderConfig
{
- /**
- * default false
- */
- public boolean useHeightmap;
- /**
- * default false
- */
- public boolean useBiomeColors;
- /**
- * default true
- */
- public boolean useSolidBlocksInColorGen;
- /**
- * default server
- */
- public DistanceGenerationMode distanceGenerationMode;
+ /**
+ * default false
+ */
+ public boolean useHeightmap;
+ /**
+ * default false
+ */
+ public boolean useBiomeColors;
+ /**
+ * default true
+ */
+ public boolean useSolidBlocksInColorGen;
+ /**
+ * default server
+ */
+ public DistanceGenerationMode distanceGenerationMode;
- /**
- * default settings for a normal chunk
- * useHeightmap = false
- * useBiomeColors = false
- * useSolidBlocksInColorGen = true
- * generationMode = Server
- */
- public LodBuilderConfig()
- {
- useHeightmap = false;
- useBiomeColors = false;
- useSolidBlocksInColorGen = true;
- distanceGenerationMode = DistanceGenerationMode.SERVER;
- }
+ /**
+ * default settings for a normal chunk
+ * useHeightmap = false
+ * useBiomeColors = false
+ * useSolidBlocksInColorGen = true
+ * generationMode = Server
+ */
+ public LodBuilderConfig()
+ {
+ useHeightmap = false;
+ useBiomeColors = false;
+ useSolidBlocksInColorGen = true;
+ distanceGenerationMode = DistanceGenerationMode.SERVER;
+ }
- /**
- * @param newUseHeightmap default = false
- * @param newUseBiomeColors default = false
- * @param newUseSolidBlocksInBiomeColor default = true
- * @param newDistanceGenerationMode default = Server
- */
- public LodBuilderConfig(boolean newUseHeightmap, boolean newUseBiomeColors,
- boolean newUseSolidBlocksInBiomeColor, DistanceGenerationMode newDistanceGenerationMode)
- {
- useHeightmap = newUseHeightmap;
- useBiomeColors = newUseBiomeColors;
- useSolidBlocksInColorGen = newUseSolidBlocksInBiomeColor;
- distanceGenerationMode = newDistanceGenerationMode;
- }
+ /**
+ * @param newUseHeightmap default = false
+ * @param newUseBiomeColors default = false
+ * @param newUseSolidBlocksInBiomeColor default = true
+ * @param newDistanceGenerationMode default = Server
+ */
+ public LodBuilderConfig(boolean newUseHeightmap, boolean newUseBiomeColors,
+ boolean newUseSolidBlocksInBiomeColor, DistanceGenerationMode newDistanceGenerationMode)
+ {
+ useHeightmap = newUseHeightmap;
+ useBiomeColors = newUseBiomeColors;
+ useSolidBlocksInColorGen = newUseSolidBlocksInBiomeColor;
+ distanceGenerationMode = newDistanceGenerationMode;
+ }
- /**
- * @param newUseHeightmap default = false
- * @param newUseBiomeColors default = false
- * @param newUseSolidBlocksInBiomeColor default = true
- * @param newDistanceGenerationMode default = Server
- */
- public LodBuilderConfig(boolean newUseHeightmap, boolean newUseBiomeColors, boolean newUseSolidBlocksInBiomeColor)
- {
- this();
- useHeightmap = newUseHeightmap;
- useBiomeColors = newUseBiomeColors;
- useSolidBlocksInColorGen = newUseSolidBlocksInBiomeColor;
- if (newUseHeightmap)
- {
- distanceGenerationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
- } else
- {
- distanceGenerationMode = DistanceGenerationMode.BIOME_ONLY;
- }
- }
+ /**
+ * @param newUseHeightmap default = false
+ * @param newUseBiomeColors default = false
+ * @param newUseSolidBlocksInBiomeColor default = true
+ * @param newDistanceGenerationMode default = Server
+ */
+ public LodBuilderConfig(boolean newUseHeightmap, boolean newUseBiomeColors, boolean newUseSolidBlocksInBiomeColor)
+ {
+ this();
+ useHeightmap = newUseHeightmap;
+ useBiomeColors = newUseBiomeColors;
+ useSolidBlocksInColorGen = newUseSolidBlocksInBiomeColor;
+ if (newUseHeightmap)
+ {
+ distanceGenerationMode = DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT;
+ } else
+ {
+ distanceGenerationMode = DistanceGenerationMode.BIOME_ONLY;
+ }
+ }
- /**
- * @param newUseHeightmap default = false
- * @param newUseBiomeColors default = false
- * @param newUseSolidBlocksInBiomeColor default = true
- * @param newDistanceGenerationMode default = Server
- */
- public LodBuilderConfig(DistanceGenerationMode newDistanceGenerationMode)
- {
- this();
- distanceGenerationMode = newDistanceGenerationMode;
- }
+ /**
+ * @param newUseHeightmap default = false
+ * @param newUseBiomeColors default = false
+ * @param newUseSolidBlocksInBiomeColor default = true
+ * @param newDistanceGenerationMode default = Server
+ */
+ public LodBuilderConfig(DistanceGenerationMode newDistanceGenerationMode)
+ {
+ this();
+ distanceGenerationMode = newDistanceGenerationMode;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/AbstractLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/AbstractLodTemplate.java
index aa656f40b..c44036940 100644
--- a/src/main/java/com/seibel/lod/builders/lodTemplates/AbstractLodTemplate.java
+++ b/src/main/java/com/seibel/lod/builders/lodTemplates/AbstractLodTemplate.java
@@ -35,17 +35,21 @@ import net.minecraft.util.math.BlockPos;
public abstract class AbstractLodTemplate
{
public abstract void addLodToBuffer(BufferBuilder buffer, BlockPos playerBlockPos, short[] data, short[][][] adjData,
- LevelPos levelPos, boolean debugging);
+ LevelPos levelPos, boolean debugging);
- /** add the given position and color to the buffer */
+ /**
+ * add the given position and color to the buffer
+ */
protected void addPosAndColor(BufferBuilder buffer,
- double x, double y, double z,
- int red, int green, int blue, int alpha)
+ double x, double y, double z,
+ int red, int green, int blue, int alpha)
{
buffer.vertex(x, y, z).color(red, green, blue, alpha).endVertex();
}
- /** Returns in bytes how much buffer memory is required
- * for one LOD object */
+ /**
+ * Returns in bytes how much buffer memory is required
+ * for one LOD object
+ */
public abstract int getBufferMemoryForSingleNode(int level);
}
diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java
index f57af98f5..0eddc9508 100644
--- a/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java
+++ b/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java
@@ -38,89 +38,89 @@ import net.minecraft.util.math.BlockPos;
*/
public class CubicLodTemplate extends AbstractLodTemplate
{
- private final int CULL_OFFSET = 16;
+ private final int CULL_OFFSET = 16;
- public CubicLodTemplate()
- {
+ public CubicLodTemplate()
+ {
- }
+ }
- @Override
- public void addLodToBuffer(BufferBuilder buffer, BlockPos playerBlockPos, short[] data, short[][][] adjData,
- LevelPos levelPos, boolean debugging)
- {
- AxisAlignedBB bbox;
+ @Override
+ public void addLodToBuffer(BufferBuilder buffer, BlockPos playerBlockPos, short[] data, short[][][] adjData,
+ LevelPos levelPos, boolean debugging)
+ {
+ AxisAlignedBB bbox;
- int width = 1 << levelPos.detailLevel;
+ int width = 1 << levelPos.detailLevel;
- // add each LOD for the detail level
- bbox = generateBoundingBox(
- DataPoint.getHeight(data),
- DataPoint.getDepth(data),
- width,
- levelPos.posX * width,
- 0,
- levelPos.posZ * width);
+ // add each LOD for the detail level
+ bbox = generateBoundingBox(
+ DataPoint.getHeight(data),
+ DataPoint.getDepth(data),
+ width,
+ levelPos.posX * width,
+ 0,
+ levelPos.posZ * width);
- int color = DataPoint.getColor(data);
- if (LodConfig.CLIENT.debugMode.get())
- {
- color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[levelPos.detailLevel].getRGB();
- }
+ int color = DataPoint.getColor(data);
+ if (LodConfig.CLIENT.debugMode.get())
+ {
+ color = LodUtil.DEBUG_DETAIL_LEVEL_COLORS[levelPos.detailLevel].getRGB();
+ }
- if (bbox != null)
- {
- addBoundingBoxToBuffer(buffer, bbox, color, playerBlockPos, adjData);
- }
+ if (bbox != null)
+ {
+ addBoundingBoxToBuffer(buffer, bbox, color, playerBlockPos, adjData);
+ }
- }
+ }
- /*
- * @Override public void addLodToBuffer(BufferBuilder buffer,
- * LodQuadTreeDimension lodDim, LodQuadTreeNode lod, double xOffset, double
- * yOffset, double zOffset, boolean debugging) { AxisAlignedBB bbox;
- *
- * bbox = generateBoundingBox( lod.getLodDataPoint().height,
- * lod.getLodDataPoint().depth, lod.width, xOffset, yOffset, zOffset);
- *
- * Color color = lod.getLodDataPoint().color;
- *
- * if (bbox != null) { addBoundingBoxToBuffer(buffer, bbox, color); }
- *
- * }
- */
+ /*
+ * @Override public void addLodToBuffer(BufferBuilder buffer,
+ * LodQuadTreeDimension lodDim, LodQuadTreeNode lod, double xOffset, double
+ * yOffset, double zOffset, boolean debugging) { AxisAlignedBB bbox;
+ *
+ * bbox = generateBoundingBox( lod.getLodDataPoint().height,
+ * lod.getLodDataPoint().depth, lod.width, xOffset, yOffset, zOffset);
+ *
+ * Color color = lod.getLodDataPoint().color;
+ *
+ * if (bbox != null) { addBoundingBoxToBuffer(buffer, bbox, color); }
+ *
+ * }
+ */
- private AxisAlignedBB generateBoundingBox(int height, int depth, int width, double xOffset, double yOffset, double zOffset)
- {
- // don't add an LOD if it is empty
- if (height == -1 && depth == -1)
- return null;
+ private AxisAlignedBB generateBoundingBox(int height, int depth, int width, double xOffset, double yOffset, double zOffset)
+ {
+ // don't add an LOD if it is empty
+ if (height == -1 && depth == -1)
+ return null;
- if (depth == height)
- {
- // if the top and bottom points are at the same height
- // render this LOD as 1 block thick
- height++;
- }
+ if (depth == height)
+ {
+ // if the top and bottom points are at the same height
+ // render this LOD as 1 block thick
+ height++;
+ }
- return new AxisAlignedBB(0, depth, 0, width, height, width).move(xOffset, yOffset, zOffset);
- }
+ return new AxisAlignedBB(0, depth, 0, width, height, width).move(xOffset, yOffset, zOffset);
+ }
- private void addBoundingBoxToBuffer(BufferBuilder buffer, AxisAlignedBB bb, int c, BlockPos playerBlockPos, short[][][] adjData)
- {
- int topColor = c;
- int bottomColor = c;
- int northColor = c;
- int southColor = c;
- int westColor = c;
- int eastColor = c;
+ private void addBoundingBoxToBuffer(BufferBuilder buffer, AxisAlignedBB bb, int c, BlockPos playerBlockPos, short[][][] adjData)
+ {
+ int topColor = c;
+ int bottomColor = c;
+ int northColor = c;
+ int southColor = c;
+ int westColor = c;
+ int eastColor = c;
- // darken the bottom and side colors if requested
- if (LodConfig.CLIENT.shadingMode.get() == ShadingMode.DARKEN_SIDES)
- {
- // the side colors are different because
- // when using fast lighting in Minecraft the north/south
- // and east/west sides are different in a similar way
+ // darken the bottom and side colors if requested
+ if (LodConfig.CLIENT.shadingMode.get() == ShadingMode.DARKEN_SIDES)
+ {
+ // the side colors are different because
+ // when using fast lighting in Minecraft the north/south
+ // and east/west sides are different in a similar way
/*
int northSouthDarkenAmount = -25;
int eastWestDarkenAmount = -50;
@@ -133,217 +133,217 @@ public class CubicLodTemplate extends AbstractLodTemplate
float northSouthDarkenAmount = 0.80f;
float eastWestDarkenAmount = 0.60f;
float bottomDarkenAmount = 0.40f;*/
- /**TODO OPTIMIZE THIS STEP*/
- topColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.UP,true));
- bottomColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.DOWN,true));
- northColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.NORTH,true));
- southColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.SOUTH,true));
- westColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.WEST,true));
- eastColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.EAST,true));
- }
+ /**TODO OPTIMIZE THIS STEP*/
+ topColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.UP, true));
+ bottomColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.DOWN, true));
+ northColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.NORTH, true));
+ southColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.SOUTH, true));
+ westColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.WEST, true));
+ eastColor = ColorUtil.applyShade(c, Minecraft.getInstance().level.getShade(Direction.EAST, true));
+ }
- // apply the user specified saturation and brightness
- float saturationMultiplier = LodConfig.CLIENT.saturationMultiplier.get().floatValue();
- float brightnessMultiplier = LodConfig.CLIENT.brightnessMultiplier.get().floatValue();
+ // apply the user specified saturation and brightness
+ float saturationMultiplier = LodConfig.CLIENT.saturationMultiplier.get().floatValue();
+ float brightnessMultiplier = LodConfig.CLIENT.brightnessMultiplier.get().floatValue();
- if(saturationMultiplier != 1 || brightnessMultiplier != 1)
- {
- topColor = ColorUtil.applySaturationAndBrightnessMultipliers(topColor, saturationMultiplier, brightnessMultiplier);
- bottomColor = ColorUtil.applySaturationAndBrightnessMultipliers(bottomColor, saturationMultiplier, brightnessMultiplier);
- northColor = ColorUtil.applySaturationAndBrightnessMultipliers(northColor, saturationMultiplier, brightnessMultiplier);
- southColor = ColorUtil.applySaturationAndBrightnessMultipliers(southColor, saturationMultiplier, brightnessMultiplier);
- westColor = ColorUtil.applySaturationAndBrightnessMultipliers(westColor, saturationMultiplier, brightnessMultiplier);
- eastColor = ColorUtil.applySaturationAndBrightnessMultipliers(eastColor, saturationMultiplier, brightnessMultiplier);
- }
- int minY;
- int maxY;
- short[] data;
+ if (saturationMultiplier != 1 || brightnessMultiplier != 1)
+ {
+ topColor = ColorUtil.applySaturationAndBrightnessMultipliers(topColor, saturationMultiplier, brightnessMultiplier);
+ bottomColor = ColorUtil.applySaturationAndBrightnessMultipliers(bottomColor, saturationMultiplier, brightnessMultiplier);
+ northColor = ColorUtil.applySaturationAndBrightnessMultipliers(northColor, saturationMultiplier, brightnessMultiplier);
+ southColor = ColorUtil.applySaturationAndBrightnessMultipliers(southColor, saturationMultiplier, brightnessMultiplier);
+ westColor = ColorUtil.applySaturationAndBrightnessMultipliers(westColor, saturationMultiplier, brightnessMultiplier);
+ eastColor = ColorUtil.applySaturationAndBrightnessMultipliers(eastColor, saturationMultiplier, brightnessMultiplier);
+ }
+ int minY;
+ int maxY;
+ short[] data;
- int red;
- int green;
- int blue;
- int alpha;
- /**TODO make all of this more automatic if possible*/
- if (playerBlockPos.getY() > bb.maxY - CULL_OFFSET)
- {
- red = ColorUtil.getRed(topColor);
- green = ColorUtil.getGreen(topColor);
- blue = ColorUtil.getBlue(topColor);
- alpha = ColorUtil.getAlpha(topColor);
- // top (facing up)
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
- }
- if (playerBlockPos.getY() < bb.minY + CULL_OFFSET)
- {
- red = ColorUtil.getRed(bottomColor);
- green = ColorUtil.getGreen(bottomColor);
- blue = ColorUtil.getBlue(bottomColor);
- alpha = ColorUtil.getAlpha(bottomColor);
- // bottom (facing down)
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
- }
+ int red;
+ int green;
+ int blue;
+ int alpha;
+ /**TODO make all of this more automatic if possible*/
+ if (playerBlockPos.getY() > bb.maxY - CULL_OFFSET)
+ {
+ red = ColorUtil.getRed(topColor);
+ green = ColorUtil.getGreen(topColor);
+ blue = ColorUtil.getBlue(topColor);
+ alpha = ColorUtil.getAlpha(topColor);
+ // top (facing up)
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ }
+ if (playerBlockPos.getY() < bb.minY + CULL_OFFSET)
+ {
+ red = ColorUtil.getRed(bottomColor);
+ green = ColorUtil.getGreen(bottomColor);
+ blue = ColorUtil.getBlue(bottomColor);
+ alpha = ColorUtil.getAlpha(bottomColor);
+ // bottom (facing down)
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
+ }
- if (playerBlockPos.getZ() > bb.minZ - CULL_OFFSET)
- {
- red = ColorUtil.getRed(northColor);
- green = ColorUtil.getGreen(northColor);
- blue = ColorUtil.getBlue(northColor);
- alpha = ColorUtil.getAlpha(northColor);
- // south (facing -Z)
- data = adjData[1][1];
- if (data == null)
- {
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
- } else
- {
- maxY = DataPoint.getHeight(data);
- if (maxY < bb.maxY)
- {
- minY = (int) Math.max(maxY, bb.minY);
- addPosAndColor(buffer, bb.maxX, minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, minY, bb.maxZ, red, green, blue, alpha);
- }
- minY = DataPoint.getDepth(data);
- if (minY > bb.minY)
- {
- maxY = (int) Math.min(minY, bb.maxY);
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
- }
- }
- }
+ if (playerBlockPos.getZ() > bb.minZ - CULL_OFFSET)
+ {
+ red = ColorUtil.getRed(northColor);
+ green = ColorUtil.getGreen(northColor);
+ blue = ColorUtil.getBlue(northColor);
+ alpha = ColorUtil.getAlpha(northColor);
+ // south (facing -Z)
+ data = adjData[1][1];
+ if (data == null)
+ {
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ } else
+ {
+ maxY = DataPoint.getHeight(data);
+ if (maxY < bb.maxY)
+ {
+ minY = (int) Math.max(maxY, bb.minY);
+ addPosAndColor(buffer, bb.maxX, minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, minY, bb.maxZ, red, green, blue, alpha);
+ }
+ minY = DataPoint.getDepth(data);
+ if (minY > bb.minY)
+ {
+ maxY = (int) Math.min(minY, bb.maxY);
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ }
+ }
+ }
- if (playerBlockPos.getZ() < bb.maxZ + CULL_OFFSET)
- {
- red = ColorUtil.getRed(southColor);
- green = ColorUtil.getGreen(southColor);
- blue = ColorUtil.getBlue(southColor);
- alpha = ColorUtil.getAlpha(southColor);
- data = adjData[1][0];
- // north (facing +Z)
- if (data == null)
- {
- addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
- } else
- {
- maxY = DataPoint.getHeight(data);
- if (maxY < bb.maxY)
- {
- minY = (int) Math.max(maxY, bb.minY);
- addPosAndColor(buffer, bb.minX, minY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, minY, bb.minZ, red, green, blue, alpha);
- }
- minY = DataPoint.getDepth(data);
- if (minY > bb.minY)
- {
- maxY = (int) Math.min(minY, bb.maxY);
- addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
- }
- }
- }
+ if (playerBlockPos.getZ() < bb.maxZ + CULL_OFFSET)
+ {
+ red = ColorUtil.getRed(southColor);
+ green = ColorUtil.getGreen(southColor);
+ blue = ColorUtil.getBlue(southColor);
+ alpha = ColorUtil.getAlpha(southColor);
+ data = adjData[1][0];
+ // north (facing +Z)
+ if (data == null)
+ {
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
+ } else
+ {
+ maxY = DataPoint.getHeight(data);
+ if (maxY < bb.maxY)
+ {
+ minY = (int) Math.max(maxY, bb.minY);
+ addPosAndColor(buffer, bb.minX, minY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, minY, bb.minZ, red, green, blue, alpha);
+ }
+ minY = DataPoint.getDepth(data);
+ if (minY > bb.minY)
+ {
+ maxY = (int) Math.min(minY, bb.maxY);
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
+ }
+ }
+ }
- if (playerBlockPos.getX() < bb.maxX + CULL_OFFSET)
- {
- red = ColorUtil.getRed(westColor);
- green = ColorUtil.getGreen(westColor);
- blue = ColorUtil.getBlue(westColor);
- alpha = ColorUtil.getAlpha(westColor);
- // west (facing -X)
- data = adjData[0][0];
- if (data == null)
- {
- addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
- } else
- {
- maxY = DataPoint.getHeight(data);
- if (maxY < bb.maxY)
- {
- minY = (int) Math.max(maxY, bb.minY);
- addPosAndColor(buffer, bb.minX, minY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
- }
- minY = DataPoint.getDepth(data);
- if (minY > bb.minY)
- {
- maxY = (int) Math.min(minY, bb.maxY);
- addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.minX, maxY, bb.minZ, red, green, blue, alpha);
- }
- }
- }
+ if (playerBlockPos.getX() < bb.maxX + CULL_OFFSET)
+ {
+ red = ColorUtil.getRed(westColor);
+ green = ColorUtil.getGreen(westColor);
+ blue = ColorUtil.getBlue(westColor);
+ alpha = ColorUtil.getAlpha(westColor);
+ // west (facing -X)
+ data = adjData[0][0];
+ if (data == null)
+ {
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ } else
+ {
+ maxY = DataPoint.getHeight(data);
+ if (maxY < bb.maxY)
+ {
+ minY = (int) Math.max(maxY, bb.minY);
+ addPosAndColor(buffer, bb.minX, minY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ }
+ minY = DataPoint.getDepth(data);
+ if (minY > bb.minY)
+ {
+ maxY = (int) Math.min(minY, bb.maxY);
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.minX, maxY, bb.minZ, red, green, blue, alpha);
+ }
+ }
+ }
- if (playerBlockPos.getX() > bb.minX - CULL_OFFSET)
- {
- red = ColorUtil.getRed(eastColor);
- green = ColorUtil.getGreen(eastColor);
- blue = ColorUtil.getBlue(eastColor);
- alpha = ColorUtil.getAlpha(eastColor);
- // east (facing +X)
- data = adjData[0][1];
- if (data == null)
- {
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
- } else
- {
- maxY = DataPoint.getHeight(data);
- if (maxY < bb.maxY)
- {
- minY = (int) Math.max(maxY, bb.minY);
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, minY, bb.minZ, red, green, blue, alpha);
- }
- minY = DataPoint.getDepth(data);
- if (minY > bb.minY)
- {
- maxY = (int) Math.min(minY, bb.maxY);
- addPosAndColor(buffer, bb.maxX, maxY, bb.minZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, maxY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
- addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
- }
- }
- }
- }
+ if (playerBlockPos.getX() > bb.minX - CULL_OFFSET)
+ {
+ red = ColorUtil.getRed(eastColor);
+ green = ColorUtil.getGreen(eastColor);
+ blue = ColorUtil.getBlue(eastColor);
+ alpha = ColorUtil.getAlpha(eastColor);
+ // east (facing +X)
+ data = adjData[0][1];
+ if (data == null)
+ {
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
+ } else
+ {
+ maxY = DataPoint.getHeight(data);
+ if (maxY < bb.maxY)
+ {
+ minY = (int) Math.max(maxY, bb.minY);
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, minY, bb.minZ, red, green, blue, alpha);
+ }
+ minY = DataPoint.getDepth(data);
+ if (minY > bb.minY)
+ {
+ maxY = (int) Math.min(minY, bb.maxY);
+ addPosAndColor(buffer, bb.maxX, maxY, bb.minZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, maxY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, red, green, blue, alpha);
+ addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, red, green, blue, alpha);
+ }
+ }
+ }
+ }
- @Override
- public int getBufferMemoryForSingleNode(int detailLevel)
- {
- // (sidesOnACube * pointsInASquare * (positionPoints + colorPoints))) *
- // howManyPointsPerLodChunk
- return (6 * 4 * (3 + 4));
- }
+ @Override
+ public int getBufferMemoryForSingleNode(int detailLevel)
+ {
+ // (sidesOnACube * pointsInASquare * (positionPoints + colorPoints))) *
+ // howManyPointsPerLodChunk
+ return (6 * 4 * (3 + 4));
+ }
}
diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/DynamicLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/DynamicLodTemplate.java
index 4c4d0411b..dcaf81f25 100644
--- a/src/main/java/com/seibel/lod/builders/lodTemplates/DynamicLodTemplate.java
+++ b/src/main/java/com/seibel/lod/builders/lodTemplates/DynamicLodTemplate.java
@@ -27,7 +27,7 @@ import net.minecraft.util.math.BlockPos;
* Chunks smoothly transition between
* each other, unless a neighboring chunk
* is at a significantly different height.
- *
+ *
* @author James Seibel
* @version 06-16-2021
*/
@@ -35,7 +35,7 @@ public class DynamicLodTemplate extends AbstractLodTemplate
{
@Override
public void addLodToBuffer(BufferBuilder buffer, BlockPos playerBlockPos, short[] data, short[][][] adjData,
- LevelPos levelPos, boolean debugging)
+ LevelPos levelPos, boolean debugging)
{
System.err.println("DynamicLodTemplate not implemented!");
}
diff --git a/src/main/java/com/seibel/lod/builders/lodTemplates/TriangularLodTemplate.java b/src/main/java/com/seibel/lod/builders/lodTemplates/TriangularLodTemplate.java
index f581fd340..a3cf999ee 100644
--- a/src/main/java/com/seibel/lod/builders/lodTemplates/TriangularLodTemplate.java
+++ b/src/main/java/com/seibel/lod/builders/lodTemplates/TriangularLodTemplate.java
@@ -25,7 +25,7 @@ import net.minecraft.util.math.BlockPos;
/**
* TODO #21 TriangularLodTemplate
* Builds each LOD chunk as a singular rectangular prism.
- *
+ *
* @author James Seibel
* @version 06-16-2021
*/
@@ -33,7 +33,7 @@ public class TriangularLodTemplate extends AbstractLodTemplate
{
@Override
public void addLodToBuffer(BufferBuilder buffer, BlockPos playerBlockPos, short[] data, short[][][] adjData,
- LevelPos levelPos, boolean debugging)
+ LevelPos levelPos, boolean debugging)
{
System.err.println("DynamicLodTemplate not implemented!");
}
diff --git a/src/main/java/com/seibel/lod/builders/worldGeneration/LodServerWorld.java b/src/main/java/com/seibel/lod/builders/worldGeneration/LodServerWorld.java
index e6245ce73..b95013703 100644
--- a/src/main/java/com/seibel/lod/builders/worldGeneration/LodServerWorld.java
+++ b/src/main/java/com/seibel/lod/builders/worldGeneration/LodServerWorld.java
@@ -65,259 +65,266 @@ import net.minecraft.world.storage.IWorldInfo;
* This allows us to keep each LodChunk generation independent
* of the actual ServerWorld, allowing us
* to multithread generation.
- *
+ *
* @author James Seibel
* @version 7-26-2021
*/
-public class LodServerWorld implements ISeedReader {
-
+public class LodServerWorld implements ISeedReader
+{
+
public HashMap
* FEATURES
* SERVER
- *
+ *
- * Added to the end of the file path when saving to prevent
- * nulling a currently existing file.
- * After the file finishes saving it will end with
- * FILE_EXTENSION.
- */
- private static final String TMP_FILE_EXTENSION = ".tmp";
+ /**
+ * lod
+ */
+ private static final String FILE_NAME_PREFIX = "lod";
+ /**
+ * .txt
+ */
+ private static final String FILE_EXTENSION = ".txt";
+ /**
+ * lod/
+ */
+ private static final String LOD_FOLDER_NAME = "lod";
+ /**
+ * detail-#
+ */
+ private static final String DETAIL_FOLDER_NAME_PREFIX = "detail-";
- /**
- * This is the file version currently accepted by this
- * file handler, older versions (smaller numbers) will be deleted and overwritten,
- * newer versions (larger numbers) will be ignored and won't be read.
- */
- public static final int LOD_SAVE_FILE_VERSION = 4;
+ /**
+ * .tmp
+ * Added to the end of the file path when saving to prevent
+ * nulling a currently existing file.
+ * After the file finishes saving it will end with
+ * FILE_EXTENSION.
+ */
+ private static final String TMP_FILE_EXTENSION = ".tmp";
- /**
- * This is the string written before the file version
- */
- private static final String LOD_FILE_VERSION_PREFIX = "lod_save_file_version";
+ /**
+ * This is the file version currently accepted by this
+ * file handler, older versions (smaller numbers) will be deleted and overwritten,
+ * newer versions (larger numbers) will be ignored and won't be read.
+ */
+ public static final int LOD_SAVE_FILE_VERSION = 4;
- /**
- * Allow saving asynchronously, but never try to save multiple regions
- * at a time
- */
- private ExecutorService fileWritingThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName()));
+ /**
+ * This is the string written before the file version
+ */
+ private static final String LOD_FILE_VERSION_PREFIX = "lod_save_file_version";
+
+ /**
+ * Allow saving asynchronously, but never try to save multiple regions
+ * at a time
+ */
+ private ExecutorService fileWritingThreadPool = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName()));
- public LodDimensionFileHandler(File newSaveFolder, LodDimension newLoadedDimension)
- {
- if (newSaveFolder == null)
- throw new IllegalArgumentException("LodDimensionFileHandler requires a valid File location to read and write to.");
+ public LodDimensionFileHandler(File newSaveFolder, LodDimension newLoadedDimension)
+ {
+ if (newSaveFolder == null)
+ throw new IllegalArgumentException("LodDimensionFileHandler requires a valid File location to read and write to.");
- dimensionDataSaveFolder = newSaveFolder;
+ dimensionDataSaveFolder = newSaveFolder;
- loadedDimension = newLoadedDimension;
- // these two variable are used in sync with the LodDimension
- regionLastWriteTime = new long[loadedDimension.getWidth()][loadedDimension.getWidth()];
- for (int i = 0; i < loadedDimension.getWidth(); i++)
- for (int j = 0; j < loadedDimension.getWidth(); j++)
- regionLastWriteTime[i][j] = -1;
- }
+ loadedDimension = newLoadedDimension;
+ // these two variable are used in sync with the LodDimension
+ regionLastWriteTime = new long[loadedDimension.getWidth()][loadedDimension.getWidth()];
+ for (int i = 0; i < loadedDimension.getWidth(); i++)
+ for (int j = 0; j < loadedDimension.getWidth(); j++)
+ regionLastWriteTime[i][j] = -1;
+ }
- //================//
- // read from file //
- //================//
+ //================//
+ // read from file //
+ //================//
/**
* Return the LodRegion region at the given coordinates.
@@ -168,8 +176,8 @@ public class LodDimensionFileHandler
bufferedReader.close();
f.delete();
ClientProxy.LOGGER.info("Outdated LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion +
- ", version requested: " + LOD_SAVE_FILE_VERSION +
- " File was been deleted.");
+ ", version requested: " + LOD_SAVE_FILE_VERSION +
+ " File was been deleted.");
continue;
} else if (fileVersion > LOD_SAVE_FILE_VERSION)
@@ -179,8 +187,8 @@ public class LodDimensionFileHandler
// want to accidently delete anything the user may want.
bufferedReader.close();
ClientProxy.LOGGER.info("Newer LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion +
- ", version requested: " + LOD_SAVE_FILE_VERSION +
- " this region will not be written to in order to protect the newer file.");
+ ", version requested: " + LOD_SAVE_FILE_VERSION +
+ " this region will not be written to in order to protect the newer file.");
continue;
}
@@ -349,38 +357,37 @@ public class LodDimensionFileHandler
}
- //================//
- // helper methods //
- //================//
+ //================//
+ // helper methods //
+ //================//
- /**
- * Return the name of the file that should contain the
- * region at the given x and z.
- * Returns null if this object isn't ready to read and write.
- *
- * example: "lod.0.0.txt"
- *
- * Returns null if there is an IO Exception.
- */
- private String getFileNameAndPathForRegion(int regionX, int regionZ, byte detailLevel)
- {
- try
- {
- // saveFolder is something like
- // ".\Super Flat\DIM-1\data"
- // or
- // ".\Super Flat\data"
- return dimensionDataSaveFolder.getCanonicalPath() + File.separatorChar +
- DETAIL_FOLDER_NAME_PREFIX + detailLevel + File.separatorChar +
- FILE_NAME_PREFIX + "." + regionX + "." + regionZ + FILE_EXTENSION;
- }
- catch (IOException | SecurityException e)
- {
- ClientProxy.LOGGER.warn("Unable to get the filename for the region [" + regionX + ", " + regionZ + "], error: [" + e.getMessage() + "], stacktrace: ");
- e.printStackTrace();
- return null;
- }
- }
+ /**
+ * Return the name of the file that should contain the
+ * region at the given x and z.
+ * Returns null if this object isn't ready to read and write.
+ *
+ *
- *
- * Returns null if the region doesn't exist
- * or is outside the loaded area.
- */
- public LodRegion getRegion(LevelPos levelPos)
- {
-
- RegionPos regionPos = levelPos.getRegionPos();
- int xIndex = (regionPos.x - center.x) + halfWidth;
- int zIndex = (regionPos.z - center.z) + halfWidth;
-
- if (!regionIsInRange(regionPos.x, regionPos.z))
- throw new ArrayIndexOutOfBoundsException("Region for level pos " + levelPos + " out of range");
- else if (regions[xIndex][zIndex] == null)
- throw new InvalidParameterException("Region for level pos " + levelPos + " not currently initialized");
- else if (regions[xIndex][zIndex].getMinDetailLevel() > levelPos.detailLevel)
- throw new InvalidParameterException("Region for level pos " + levelPos + " currently only reach level " + regions[xIndex][zIndex].getMinDetailLevel());
- return regions[xIndex][zIndex];
- }
-
- /**
- * Gets the region at the given X and Z
- *
- * Returns null if the region doesn't exist
- * or is outside the loaded area.
- */
- public LodRegion getRegion(RegionPos regionPos)
- {
- int xIndex = (regionPos.x - center.x) + halfWidth;
- int zIndex = (regionPos.z - center.z) + halfWidth;
-
- if (!regionIsInRange(regionPos.x, regionPos.z))
- throw new ArrayIndexOutOfBoundsException("Region " + regionPos + " out of range");
- else if (regions[xIndex][zIndex] == null)
- throw new InvalidParameterException("Region " + regionPos + " not currently initialized");
- return regions[xIndex][zIndex];
- }
-
- /**
- * Overwrite the LodRegion at the location of newRegion with newRegion.
- *
- * @throws ArrayIndexOutOfBoundsException if newRegion is outside what can be stored in this LodDimension.
- */
- public synchronized void addOrOverwriteRegion(LodRegion newRegion) throws ArrayIndexOutOfBoundsException
- {
- int xIndex = (newRegion.regionPosX - center.x) + halfWidth;
- int zIndex = (center.z - newRegion.regionPosZ) + halfWidth;
-
- if (!regionIsInRange(newRegion.regionPosX, newRegion.regionPosZ))
- // out of range
- throw new ArrayIndexOutOfBoundsException("Region " + newRegion.regionPosX + ", " + newRegion.regionPosZ + " out of range");
-
- regions[xIndex][zIndex] = newRegion;
- }
-
-
- /**
- *
- */
- public void treeCutter(int playerPosX, int playerPosZ)
- {
- ChunkPos newPlayerChunk = (new LevelPos((byte) 0, playerPosX, playerPosZ)).getChunkPos();
- if (lastCutChunk == null)
- lastCutChunk = new ChunkPos(newPlayerChunk.x + 1, newPlayerChunk.z - 1);
- if (newPlayerChunk.x != lastCutChunk.x || newPlayerChunk.z != lastCutChunk.z)
- {
- lastCutChunk = newPlayerChunk;
- Thread thread = new Thread(() ->
- {
- int regionX;
- int regionZ;
- LevelPos levelPos = new LevelPos();
-
- for (int x = 0; x < regions.length; x++)
- {
- for (int z = 0; z < regions.length; z++)
- {
- regionX = (x + center.x) - halfWidth;
- regionZ = (z + center.z) - halfWidth;
- levelPos.changeParameters(LodUtil.REGION_DETAIL_LEVEL, regionX, regionZ);
- //we start checking from the first circle. If the whole region is in the circle
- //we proceed to cut all the level lower than the level of circle 1 and we break
- //if this is not the case w
- for (byte index = LodUtil.BLOCK_DETAIL_LEVEL; index <= LodUtil.DETAIL_OPTIONS; index++)
- {
- if (DetailDistanceUtil.getDistanceTreeCut(index + 1) > levelPos.minDistance(playerPosX, playerPosZ))
- {
-
- byte cutDetailLevel = DetailDistanceUtil.getCutLodDetail(index);
-
- if (regions[x][z] != null)
- {
- if (regions[x][z].getMinDetailLevel() > cutDetailLevel)
- {
- regions[x][z].cutTree(cutDetailLevel);
- }
- }
- //once we
- break;
- }
- }
- }// region z
- }// region z
-
- });
- cutAndGenThreads.execute(thread);
- }
- }
-
- /**
- *
- */
- public void treeGenerator(int playerPosX, int playerPosZ)
- {
-
- ChunkPos newPlayerChunk = (new LevelPos((byte) 0, playerPosX, playerPosZ)).getChunkPos();
-
- if (lastGenChunk == null)
- lastGenChunk = new ChunkPos(newPlayerChunk.x + 1, newPlayerChunk.z - 1);
- if (newPlayerChunk.x != lastGenChunk.x || newPlayerChunk.z != lastGenChunk.z)
- {
- lastGenChunk = newPlayerChunk;
- Thread thread = new Thread(() ->
- {
- int regionX;
- int regionZ;
- LodRegion region;
- LevelPos levelPos = new LevelPos();
- List
- * Returns null if the LodChunk doesn't exist or
- * is outside the loaded area.
- */
- public short[] getData(ChunkPos chunkPos)
- {
- LevelPos levelPos = new LevelPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.x, chunkPos.z);
- return getData(levelPos);
- }
-
- /**
- * Get the data point at the given X and Z coordinates
- * in this dimension.
- *
- * Returns null if the LodChunk doesn't exist or
- * is outside the loaded area.
- */
- public short[] getData(LevelPos levelPos)
- {
- if (levelPos.detailLevel > LodUtil.REGION_DETAIL_LEVEL)
- throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + levelPos.detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
-
- try
- {
- LodRegion region = getRegion(levelPos);
-
- if (region == null)
- {
- return null;
- }
-
- return region.getData(levelPos);
-
- } catch (Exception e)
- {
- return null;
- }
- }
-
-
- /**
- * Get the data point at the given X and Z coordinates
- * in this dimension.
- *
- * Returns null if the LodChunk doesn't exist or
- * is outside the loaded area.
- */
- public void updateData(LevelPos levelPos)
- {
- if (levelPos.detailLevel > LodUtil.REGION_DETAIL_LEVEL)
- throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + levelPos.detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
-
- LodRegion region = getRegion(levelPos);
-
-
- if (region == null)
- {
- return;
- }
- region.updateArea(levelPos);
- }
-
- /**
- * return true if and only if the node at that position exist
- */
-
- public boolean hasThisPositionBeenGenerated(LevelPos levelPos)
- {
- LodRegion region = getRegion(levelPos);
-
- if (region == null)
- {
- return false;
- }
-
- return region.hasDataBeenGenerated(levelPos);
- }
-
- /**
- * return true if and only if the node at that position exist
- */
- public boolean doesDataExist(LevelPos levelPos)
- {
- try
- {
- LodRegion region = getRegion(levelPos);
-
- if (region == null)
- {
- return false;
- }
-
- return region.doesDataExist(levelPos.clone());
- } catch (Exception e)
- {
- return false;
- }
- }
-
- /**
- * return true if and only if the node at that position exist
- */
- public DistanceGenerationMode getGenerationMode(LevelPos levelPos)
- {
- LodRegion region = getRegion(levelPos);
-
- if (region == null)
- {
- return DistanceGenerationMode.NONE;
- }
-
- return region.getGenerationMode(levelPos);
- }
-
- /**
- * Get the region at the given X and Z coordinates from the
- * RegionFileHandler.
- */
- public LodRegion getRegionFromFile(RegionPos regionPos, byte detailLevel)
- {
- if (fileHandler != null)
- return fileHandler.loadRegionFromFile(regionPos, detailLevel);
- else
- return null;
- }
-
- /**
- * Save all dirty regions in this LodDimension to file.
- */
- public void saveDirtyRegionsToFileAsync()
- {
- fileHandler.saveDirtyRegionsToFileAsync();
- }
-
-
- /**
- * Returns whether the region at the given X and Z coordinates
- * is within the loaded range.
- */
- public boolean regionIsInRange(int regionX, int regionZ)
- {
- int xIndex = (regionX - center.x) + halfWidth;
- int zIndex = (regionZ - center.z) + halfWidth;
-
- return xIndex >= 0 && xIndex < width && zIndex >= 0 && zIndex < width;
- }
-
-
- public int getCenterX()
- {
- return center.x;
- }
-
- public int getCenterZ()
- {
- return center.z;
- }
-
-
- public int getWidth()
- {
- if (regions != null)
- {
- // we want to get the length directly from the
- // source to make sure it is in sync with region
- // and isRegionDirty
- return regions.length;
- } else
- {
- return width;
- }
- }
-
- public void setRegionWidth(int newWidth)
- {
- width = newWidth;
- halfWidth = (int) Math.floor(width / 2);
-
- regions = new LodRegion[width][width];
- isRegionDirty = new boolean[width][width];
-
- // populate isRegionDirty
- for (int i = 0; i < width; i++)
- for (int j = 0; j < width; j++)
- isRegionDirty[i][j] = false;
- }
-
-
- @Override
- public String toString()
- {
- int regionX;
- int regionZ;
- LevelPos levelPos;
- LodRegion region;
-
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.append("Dimension : \n");
- for (int x = 0; x < regions.length; x++)
- {
- for (int z = 0; z < regions.length; z++)
- {
- region = regions[x][z];
- if (region == null)
- {
- stringBuilder.append("n");
- stringBuilder.append("\t");
-
- } else
- {
- stringBuilder.append(region.getMinDetailLevel());
- stringBuilder.append("\t");
- }
- }
- stringBuilder.append("\n");
- }
- System.out.println(stringBuilder);
- return stringBuilder.toString();
- }
+ public final DimensionType dimension;
+
+ /**
+ * measured in regions
+ */
+ private volatile int width;
+ /**
+ * measured in regions
+ */
+ private volatile int halfWidth;
+
+
+ public volatile LodRegion regions[][];
+ public volatile boolean isRegionDirty[][];
+
+ private volatile RegionPos center;
+ private volatile ChunkPos lastGenChunk;
+ private volatile ChunkPos lastCutChunk;
+ private LodDimensionFileHandler fileHandler;
+ private ExecutorService cutAndGenThreads = Executors.newSingleThreadExecutor(new LodThreadFactory(this.getClass().getSimpleName() + " - cutAndGen"));
+
+ /**
+ * Creates the dimension centered at (0,0)
+ *
+ * @param newWidth in regions
+ */
+ public LodDimension(DimensionType newDimension, LodWorld lodWorld, int newWidth)
+ {
+ lastCutChunk = null;
+ lastGenChunk = null;
+ dimension = newDimension;
+ width = newWidth;
+ halfWidth = (int) Math.floor(width / 2);
+ Minecraft mc = Minecraft.getInstance();
+ if (newDimension != null && lodWorld != null)
+ {
+ try
+ {
+
+ File saveDir;
+ if (mc.hasSingleplayerServer())
+ {
+ // local world
+
+ ServerWorld serverWorld = LodUtil.getServerWorldFromDimension(newDimension);
+
+ // provider needs a separate variable to prevent
+ // the compiler from complaining
+ ServerChunkProvider provider = serverWorld.getChunkSource();
+ saveDir = new File(provider.dataStorage.dataFolder.getCanonicalFile().getPath() + File.separatorChar + "lod");
+ } else
+ {
+ // connected to server
+
+ saveDir = new File(mc.gameDirectory.getCanonicalFile().getPath() +
+ File.separatorChar + "lod server data" + File.separatorChar + LodUtil.getDimensionIDFromWorld(mc.level));
+ }
+
+ fileHandler = new LodDimensionFileHandler(saveDir, this);
+ } catch (IOException e)
+ {
+ // the file handler wasn't able to be created
+ // we won't be able to read or write any files
+ }
+ }
+
+
+ regions = new LodRegion[width][width];
+ isRegionDirty = new boolean[width][width];
+
+ //treeGenerator((int) mc.player.getX(),(int) mc.player.getZ());
+
+ // populate isRegionDirty
+ for (int i = 0; i < width; i++)
+ for (int j = 0; j < width; j++)
+ isRegionDirty[i][j] = false;
+
+ center = new RegionPos(0, 0);
+ }
+
+
+ /**
+ * Move the center of this LodDimension and move all owned
+ * regions over by the given x and z offset.
+ *
+ * Returns null if the region doesn't exist
+ * or is outside the loaded area.
+ */
+ public LodRegion getRegion(LevelPos levelPos)
+ {
+
+ RegionPos regionPos = levelPos.getRegionPos();
+ int xIndex = (regionPos.x - center.x) + halfWidth;
+ int zIndex = (regionPos.z - center.z) + halfWidth;
+
+ if (!regionIsInRange(regionPos.x, regionPos.z))
+ throw new ArrayIndexOutOfBoundsException("Region for level pos " + levelPos + " out of range");
+ else if (regions[xIndex][zIndex] == null)
+ throw new InvalidParameterException("Region for level pos " + levelPos + " not currently initialized");
+ else if (regions[xIndex][zIndex].getMinDetailLevel() > levelPos.detailLevel)
+ throw new InvalidParameterException("Region for level pos " + levelPos + " currently only reach level " + regions[xIndex][zIndex].getMinDetailLevel());
+ return regions[xIndex][zIndex];
+ }
+
+ /**
+ * Gets the region at the given X and Z
+ *
+ * Returns null if the region doesn't exist
+ * or is outside the loaded area.
+ */
+ public LodRegion getRegion(RegionPos regionPos)
+ {
+ int xIndex = (regionPos.x - center.x) + halfWidth;
+ int zIndex = (regionPos.z - center.z) + halfWidth;
+
+ if (!regionIsInRange(regionPos.x, regionPos.z))
+ throw new ArrayIndexOutOfBoundsException("Region " + regionPos + " out of range");
+ else if (regions[xIndex][zIndex] == null)
+ throw new InvalidParameterException("Region " + regionPos + " not currently initialized");
+ return regions[xIndex][zIndex];
+ }
+
+ /**
+ * Overwrite the LodRegion at the location of newRegion with newRegion.
+ *
+ * @throws ArrayIndexOutOfBoundsException if newRegion is outside what can be stored in this LodDimension.
+ */
+ public synchronized void addOrOverwriteRegion(LodRegion newRegion) throws ArrayIndexOutOfBoundsException
+ {
+ int xIndex = (newRegion.regionPosX - center.x) + halfWidth;
+ int zIndex = (center.z - newRegion.regionPosZ) + halfWidth;
+
+ if (!regionIsInRange(newRegion.regionPosX, newRegion.regionPosZ))
+ // out of range
+ throw new ArrayIndexOutOfBoundsException("Region " + newRegion.regionPosX + ", " + newRegion.regionPosZ + " out of range");
+
+ regions[xIndex][zIndex] = newRegion;
+ }
+
+
+ /**
+ *
+ */
+ public void treeCutter(int playerPosX, int playerPosZ)
+ {
+ ChunkPos newPlayerChunk = (new LevelPos((byte) 0, playerPosX, playerPosZ)).getChunkPos();
+ if (lastCutChunk == null)
+ lastCutChunk = new ChunkPos(newPlayerChunk.x + 1, newPlayerChunk.z - 1);
+ if (newPlayerChunk.x != lastCutChunk.x || newPlayerChunk.z != lastCutChunk.z)
+ {
+ lastCutChunk = newPlayerChunk;
+ Thread thread = new Thread(() ->
+ {
+ int regionX;
+ int regionZ;
+ LevelPos levelPos = new LevelPos();
+
+ for (int x = 0; x < regions.length; x++)
+ {
+ for (int z = 0; z < regions.length; z++)
+ {
+ regionX = (x + center.x) - halfWidth;
+ regionZ = (z + center.z) - halfWidth;
+ levelPos.changeParameters(LodUtil.REGION_DETAIL_LEVEL, regionX, regionZ);
+ //we start checking from the first circle. If the whole region is in the circle
+ //we proceed to cut all the level lower than the level of circle 1 and we break
+ //if this is not the case w
+ for (byte index = LodUtil.BLOCK_DETAIL_LEVEL; index <= LodUtil.DETAIL_OPTIONS; index++)
+ {
+ if (DetailDistanceUtil.getDistanceTreeCut(index + 1) > levelPos.minDistance(playerPosX, playerPosZ))
+ {
+
+ byte cutDetailLevel = DetailDistanceUtil.getCutLodDetail(index);
+
+ if (regions[x][z] != null)
+ {
+ if (regions[x][z].getMinDetailLevel() > cutDetailLevel)
+ {
+ regions[x][z].cutTree(cutDetailLevel);
+ }
+ }
+ //once we
+ break;
+ }
+ }
+ }// region z
+ }// region z
+
+ });
+ cutAndGenThreads.execute(thread);
+ }
+ }
+
+ /**
+ *
+ */
+ public void treeGenerator(int playerPosX, int playerPosZ)
+ {
+
+ ChunkPos newPlayerChunk = (new LevelPos((byte) 0, playerPosX, playerPosZ)).getChunkPos();
+
+ if (lastGenChunk == null)
+ lastGenChunk = new ChunkPos(newPlayerChunk.x + 1, newPlayerChunk.z - 1);
+ if (newPlayerChunk.x != lastGenChunk.x || newPlayerChunk.z != lastGenChunk.z)
+ {
+ lastGenChunk = newPlayerChunk;
+ Thread thread = new Thread(() ->
+ {
+ int regionX;
+ int regionZ;
+ LodRegion region;
+ LevelPos levelPos = new LevelPos();
+ List
+ * Returns null if the LodChunk doesn't exist or
+ * is outside the loaded area.
+ */
+ public short[] getData(ChunkPos chunkPos)
+ {
+ LevelPos levelPos = new LevelPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.x, chunkPos.z);
+ return getData(levelPos);
+ }
+
+ /**
+ * Get the data point at the given X and Z coordinates
+ * in this dimension.
+ *
+ * Returns null if the LodChunk doesn't exist or
+ * is outside the loaded area.
+ */
+ public short[] getData(LevelPos levelPos)
+ {
+ if (levelPos.detailLevel > LodUtil.REGION_DETAIL_LEVEL)
+ throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + levelPos.detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
+
+ try
+ {
+ LodRegion region = getRegion(levelPos);
+
+ if (region == null)
+ {
+ return null;
+ }
+
+ return region.getData(levelPos);
+
+ } catch (Exception e)
+ {
+ return null;
+ }
+ }
+
+
+ /**
+ * Get the data point at the given X and Z coordinates
+ * in this dimension.
+ *
+ * Returns null if the LodChunk doesn't exist or
+ * is outside the loaded area.
+ */
+ public void updateData(LevelPos levelPos)
+ {
+ if (levelPos.detailLevel > LodUtil.REGION_DETAIL_LEVEL)
+ throw new IllegalArgumentException("getLodFromCoordinates given a level of \"" + levelPos.detailLevel + "\" when \"" + LodUtil.REGION_DETAIL_LEVEL + "\" is the max.");
+
+ LodRegion region = getRegion(levelPos);
+
+
+ if (region == null)
+ {
+ return;
+ }
+ region.updateArea(levelPos);
+ }
+
+ /**
+ * return true if and only if the node at that position exist
+ */
+
+ public boolean hasThisPositionBeenGenerated(LevelPos levelPos)
+ {
+ LodRegion region = getRegion(levelPos);
+
+ if (region == null)
+ {
+ return false;
+ }
+
+ return region.hasDataBeenGenerated(levelPos);
+ }
+
+ /**
+ * return true if and only if the node at that position exist
+ */
+ public boolean doesDataExist(LevelPos levelPos)
+ {
+ try
+ {
+ LodRegion region = getRegion(levelPos);
+
+ if (region == null)
+ {
+ return false;
+ }
+
+ return region.doesDataExist(levelPos.clone());
+ } catch (Exception e)
+ {
+ return false;
+ }
+ }
+
+ /**
+ * return true if and only if the node at that position exist
+ */
+ public DistanceGenerationMode getGenerationMode(LevelPos levelPos)
+ {
+ LodRegion region = getRegion(levelPos);
+
+ if (region == null)
+ {
+ return DistanceGenerationMode.NONE;
+ }
+
+ return region.getGenerationMode(levelPos);
+ }
+
+ /**
+ * Get the region at the given X and Z coordinates from the
+ * RegionFileHandler.
+ */
+ public LodRegion getRegionFromFile(RegionPos regionPos, byte detailLevel)
+ {
+ if (fileHandler != null)
+ return fileHandler.loadRegionFromFile(regionPos, detailLevel);
+ else
+ return null;
+ }
+
+ /**
+ * Save all dirty regions in this LodDimension to file.
+ */
+ public void saveDirtyRegionsToFileAsync()
+ {
+ fileHandler.saveDirtyRegionsToFileAsync();
+ }
+
+
+ /**
+ * Returns whether the region at the given X and Z coordinates
+ * is within the loaded range.
+ */
+ public boolean regionIsInRange(int regionX, int regionZ)
+ {
+ int xIndex = (regionX - center.x) + halfWidth;
+ int zIndex = (regionZ - center.z) + halfWidth;
+
+ return xIndex >= 0 && xIndex < width && zIndex >= 0 && zIndex < width;
+ }
+
+
+ public int getCenterX()
+ {
+ return center.x;
+ }
+
+ public int getCenterZ()
+ {
+ return center.z;
+ }
+
+
+ public int getWidth()
+ {
+ if (regions != null)
+ {
+ // we want to get the length directly from the
+ // source to make sure it is in sync with region
+ // and isRegionDirty
+ return regions.length;
+ } else
+ {
+ return width;
+ }
+ }
+
+ public void setRegionWidth(int newWidth)
+ {
+ width = newWidth;
+ halfWidth = (int) Math.floor(width / 2);
+
+ regions = new LodRegion[width][width];
+ isRegionDirty = new boolean[width][width];
+
+ // populate isRegionDirty
+ for (int i = 0; i < width; i++)
+ for (int j = 0; j < width; j++)
+ isRegionDirty[i][j] = false;
+ }
+
+
+ @Override
+ public String toString()
+ {
+ int regionX;
+ int regionZ;
+ LevelPos levelPos;
+ LodRegion region;
+
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.append("Dimension : \n");
+ for (int x = 0; x < regions.length; x++)
+ {
+ for (int z = 0; z < regions.length; z++)
+ {
+ region = regions[x][z];
+ if (region == null)
+ {
+ stringBuilder.append("n");
+ stringBuilder.append("\t");
+
+ } else
+ {
+ stringBuilder.append(region.getMinDetailLevel());
+ stringBuilder.append("\t");
+ }
+ }
+ stringBuilder.append("\n");
+ }
+ System.out.println(stringBuilder);
+ return stringBuilder.toString();
+ }
}
diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java
index c06955431..6307106b7 100644
--- a/src/main/java/com/seibel/lod/objects/LodRegion.java
+++ b/src/main/java/com/seibel/lod/objects/LodRegion.java
@@ -22,675 +22,675 @@ import net.minecraft.util.math.ChunkPos;
public class LodRegion implements Serializable
{
- //x coord,
- private byte minDetailLevel;
- private static final byte POSSIBLE_LOD = 10;
- private int numberOfPoints;
-
- //For each of the following field the first slot is for the level of detail
- //Important: byte have a [-128, 127] range. When converting from or to int a 128 should be added or removed
- //If there is a bug with color then it's probably caused by this.
- //in the future other fields like transparency and light level could be added
- private byte[][][][] colors;
-
- private short[][][] height;
-
- private short[][][] depth;
-
- //a new node will have 0 as generationType
- //a node with 1 is node
- private byte[][][] generationType;
-
- private boolean[][][] dataExistence;
-
- public final int regionPosX;
- public final int regionPosZ;
-
- public LodRegion(LevelContainer levelContainer, RegionPos regionPos)
- {
- this.regionPosX = regionPos.x;
- this.regionPosZ = regionPos.z;
- this.minDetailLevel = levelContainer.detailLevel;
-
- //Array of matrices of arrays
- colors = new byte[POSSIBLE_LOD][][][];
-
- //Arrays of matrices
- height = new short[POSSIBLE_LOD][][];
- depth = new short[POSSIBLE_LOD][][];
- generationType = new byte[POSSIBLE_LOD][][];
- dataExistence = new boolean[POSSIBLE_LOD][][];
-
- colors[minDetailLevel] = levelContainer.colors;
- height[minDetailLevel] = levelContainer.height;
- depth[minDetailLevel] = levelContainer.depth;
- generationType[minDetailLevel] = levelContainer.generationType;
- dataExistence[minDetailLevel] = levelContainer.dataExistence;
-
- //Initialize all the different matrices
- for (byte lod = (byte) (minDetailLevel + 1); lod <= LodUtil.REGION_DETAIL_LEVEL; lod++)
- {
- int size = (short) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - lod);
- colors[lod] = new byte[size][size][3];
- height[lod] = new short[size][size];
- depth[lod] = new short[size][size];
- generationType[lod] = new byte[size][size];
- dataExistence[lod] = new boolean[size][size];
- }
- int width;
- LevelPos levelPos = new LevelPos();
- for (byte tempLod = (byte) (minDetailLevel + 1); tempLod <= LodUtil.REGION_DETAIL_LEVEL; tempLod++)
- {
- width = 1 << (LodUtil.REGION_DETAIL_LEVEL - tempLod);
- for (int x = 0; x < width; x++)
- {
- for (int z = 0; z < width; z++)
- {
- levelPos.changeParameters(tempLod, x, z);
- update(levelPos);
- }
- }
- }
- }
-
- public LodRegion(byte minDetailLevel, RegionPos regionPos)
- {
- this.minDetailLevel = minDetailLevel;
- this.regionPosX = regionPos.x;
- this.regionPosZ = regionPos.z;
-
- //Array of matrices of arrays
- colors = new byte[POSSIBLE_LOD][][][];
-
- //Arrays of matrices
- height = new short[POSSIBLE_LOD][][];
- depth = new short[POSSIBLE_LOD][][];
- generationType = new byte[POSSIBLE_LOD][][];
- dataExistence = new boolean[POSSIBLE_LOD][][];
-
-
- //Initialize all the different matrices
- for (byte lod = minDetailLevel; lod <= LodUtil.REGION_DETAIL_LEVEL; lod++)
- {
- int size = (short) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - lod);
- colors[lod] = new byte[size][size][3];
- height[lod] = new short[size][size];
- depth[lod] = new short[size][size];
- generationType[lod] = new byte[size][size];
- dataExistence[lod] = new boolean[size][size];
-
- }
- }
-
- /**
- * This method can be used to insert data into the LodRegion
- *
- * @param levelPos
- * @param dataPoint
- * @param generationType
- * @return
- */
- public boolean addData(LevelPos levelPos, short[] dataPoint, byte generationType)
- {
- levelPos.performRegionModule();
- if ((this.generationType[levelPos.detailLevel][levelPos.posX][levelPos.posZ] == 0) || (generationType >= this.generationType[levelPos.detailLevel][levelPos.posX][levelPos.posZ]))
- {
-
- //update the number of node present
- if (this.dataExistence[levelPos.detailLevel][levelPos.posX][levelPos.posZ]) numberOfPoints++;
-
- //add the node data
- this.height[levelPos.detailLevel][levelPos.posX][levelPos.posZ] = DataPoint.getHeight(dataPoint);
- this.depth[levelPos.detailLevel][levelPos.posX][levelPos.posZ] = DataPoint.getDepth(dataPoint);
- this.colors[levelPos.detailLevel][levelPos.posX][levelPos.posZ][0] = (byte) (DataPoint.getRed(dataPoint) - 128);
- this.colors[levelPos.detailLevel][levelPos.posX][levelPos.posZ][1] = (byte) (DataPoint.getGreen(dataPoint) - 128);
- this.colors[levelPos.detailLevel][levelPos.posX][levelPos.posZ][2] = (byte) (DataPoint.getBlue(dataPoint) - 128);
- this.generationType[levelPos.detailLevel][levelPos.posX][levelPos.posZ] = generationType;
- this.dataExistence[levelPos.detailLevel][levelPos.posX][levelPos.posZ] = true;
- return true;
- } else
- {
- return false;
- }
- }
-
-
- public short[] getData(ChunkPos chunkPos)
- {
- return getData(new LevelPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.x, chunkPos.z));
- }
-
- /**
- * This method will return the data in the position relative to the level of detail
- *
- * @param lod
- * @return the data at the relative pos and level
- */
- public short[] getData(byte lod, BlockPos blockPos)
- {
- int posX = Math.floorMod(blockPos.getX(), (int) Math.pow(2, lod));
- int posZ = Math.floorMod(blockPos.getZ(), (int) Math.pow(2, lod));
- return getData(new LevelPos(lod, posX, posZ));
- }
-
- /**
- * This method will return the data in the position relative to the level of detail
- *
- * @param levelPos
- * @return the data at the relative pos and level
- */
- public short[] getData(LevelPos levelPos)
- {
- levelPos = levelPos.getRegionModuleLevelPos();
- return new short[]{height[levelPos.detailLevel][levelPos.posX][levelPos.posZ],
- depth[levelPos.detailLevel][levelPos.posX][levelPos.posZ],
- (short) (colors[levelPos.detailLevel][levelPos.posX][levelPos.posZ][0] + 128),
- (short) (colors[levelPos.detailLevel][levelPos.posX][levelPos.posZ][1] + 128),
- (short) (colors[levelPos.detailLevel][levelPos.posX][levelPos.posZ][2] + 128)
- };
- }
-
- /**
- * This method will return all the levelPos that are renderable according to the requisite given in input
- *
- * @return
- */
- public List
- * This should be done whenever loading a new world.
- *
- * @param newWorldName name of the world
- */
- public void selectWorld(String newWorldName)
- {
- if (newWorldName.isEmpty())
- {
- deselectWorld();
- return;
- }
+ /**
+ * Set up the LodQuadTreeWorld with the given newWorldName.
+ * This should be done whenever loading a new world.
+ *
+ * @param newWorldName name of the world
+ */
+ public void selectWorld(String newWorldName)
+ {
+ if (newWorldName.isEmpty())
+ {
+ deselectWorld();
+ return;
+ }
- if (worldName.equals(newWorldName))
- // don't recreate everything if we
- // didn't actually change worlds
- return;
+ if (worldName.equals(newWorldName))
+ // don't recreate everything if we
+ // didn't actually change worlds
+ return;
- worldName = newWorldName;
- lodDimensions = new Hashtable
- * This should be done whenever unloaded a world.
- */
- public void deselectWorld()
- {
- worldName = NO_WORLD_LOADED;
- lodDimensions = null;
- isWorldLoaded = false;
- }
+ /**
+ * Set the worldName to "No world loaded"
+ * and clear the lodDimensions Map.
+ * This should be done whenever unloaded a world.
+ */
+ public void deselectWorld()
+ {
+ worldName = NO_WORLD_LOADED;
+ lodDimensions = null;
+ isWorldLoaded = false;
+ }
- /**
- * Adds newStorage to this world, if a LodQuadTreeDimension
- * already exists for the given dimension it is replaced.
- */
- public void addLodDimension(LodDimension newStorage)
- {
- if (lodDimensions == null)
- return;
+ /**
+ * Adds newStorage to this world, if a LodQuadTreeDimension
+ * already exists for the given dimension it is replaced.
+ */
+ public void addLodDimension(LodDimension newStorage)
+ {
+ if (lodDimensions == null)
+ return;
- lodDimensions.put(newStorage.dimension, newStorage);
- }
+ lodDimensions.put(newStorage.dimension, newStorage);
+ }
- /**
- * Returns null if no LodQuadTreeDimension exists for the given dimension
- */
- public LodDimension getLodDimension(DimensionType dimension)
- {
- if (lodDimensions == null)
- return null;
+ /**
+ * Returns null if no LodQuadTreeDimension exists for the given dimension
+ */
+ public LodDimension getLodDimension(DimensionType dimension)
+ {
+ if (lodDimensions == null)
+ return null;
- return lodDimensions.get(dimension);
- }
+ return lodDimensions.get(dimension);
+ }
- /**
- * Resizes the max width in regions that each LodDimension
- * should use.
- */
- public void resizeDimensionRegionWidth(int newWidth)
- {
- if (lodDimensions == null)
- return;
+ /**
+ * Resizes the max width in regions that each LodDimension
+ * should use.
+ */
+ public void resizeDimensionRegionWidth(int newWidth)
+ {
+ if (lodDimensions == null)
+ return;
- saveAllDimensions();
+ saveAllDimensions();
- for (DimensionType key : lodDimensions.keySet())
- lodDimensions.get(key).setRegionWidth(newWidth);
- }
+ for (DimensionType key : lodDimensions.keySet())
+ lodDimensions.get(key).setRegionWidth(newWidth);
+ }
- /**
- * Requests all dimensions save any dirty regions they may have.
- */
- public void saveAllDimensions()
- {
- if (lodDimensions == null)
- return;
+ /**
+ * Requests all dimensions save any dirty regions they may have.
+ */
+ public void saveAllDimensions()
+ {
+ if (lodDimensions == null)
+ return;
- ClientProxy.LOGGER.info("Saving LODs");
+ ClientProxy.LOGGER.info("Saving LODs");
- for (DimensionType key : lodDimensions.keySet())
- lodDimensions.get(key).saveDirtyRegionsToFileAsync();
- }
+ for (DimensionType key : lodDimensions.keySet())
+ lodDimensions.get(key).saveDirtyRegionsToFileAsync();
+ }
- public boolean getIsWorldLoaded()
- {
- return isWorldLoaded;
- }
+ public boolean getIsWorldLoaded()
+ {
+ return isWorldLoaded;
+ }
- public String getWorldName()
- {
- return worldName;
- }
+ public String getWorldName()
+ {
+ return worldName;
+ }
- @Override
- public String toString()
- {
- return "World name: " + worldName;
- }
+ @Override
+ public String toString()
+ {
+ return "World name: " + worldName;
+ }
}
diff --git a/src/main/java/com/seibel/lod/objects/RegionPos.java b/src/main/java/com/seibel/lod/objects/RegionPos.java
index 7fbf9ef50..27c7100ac 100644
--- a/src/main/java/com/seibel/lod/objects/RegionPos.java
+++ b/src/main/java/com/seibel/lod/objects/RegionPos.java
@@ -24,7 +24,7 @@ import net.minecraft.util.math.ChunkPos;
/**
* This object is similar to ChunkPos or BlockPos.
- *
+ *
* @author James Seibel
* @version 8-21-2021
*/
@@ -32,11 +32,11 @@ public class RegionPos
{
public int x;
public int z;
-
-
+
+
/**
* Default Constructor
- *
+ *