diff --git a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java
index 66393a5cf..da2a42865 100644
--- a/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java
+++ b/src/main/java/com/seibel/lod/builders/lodBuilding/LodBuilder.java
@@ -110,10 +110,6 @@ public class LodBuilder
/** Minecraft's max light value */
public static final short DEFAULT_MAX_LIGHT = 15;
- /** TODO is this needed / used? */
- public static final boolean avoidNonFullBlock = false;
- /** TODO is this needed / used? */
- public static final boolean avoidSmallBlock = false;
/**
* How wide LodDimensions should be in regions
@@ -788,18 +784,17 @@ public class LodBuilder
private boolean isLayerValidLodPoint(IChunk chunk, BlockPos.Mutable blockPos)
{
BlockState blockState = chunk.getBlockState(blockPos);
-
-
+ boolean avoidNonFullBlock = LodConfig.CLIENT.worldGenerator.avoidNonFullBlock.get();
+ boolean avoidBlockWithNoCollision = LodConfig.CLIENT.worldGenerator.avoidBlockWithNoCollision.get();
if (blockState != null)
{
// TODO this code is dead since avoidSmallBlock and onlyUseFullBlock
// are set to false and are never changed.
// should this code be changed?
- if (avoidSmallBlock || avoidNonFullBlock)
+
+ if (avoidNonFullBlock)
{
- if (!smallBlock.containsKey(blockState.getBlock())
- || smallBlock.get(blockState.getBlock()) == null
- || !notFullBlock.containsKey(blockState.getBlock())
+ if (!notFullBlock.containsKey(blockState.getBlock())
|| notFullBlock.get(blockState.getBlock()) == null
)
{
@@ -807,7 +802,6 @@ public class LodBuilder
if (!blockState.getFluidState().isEmpty())
{
notFullBlock.put(blockState.getBlock(), false);
- smallBlock.put(blockState.getBlock(), false);
}
if (!voxelShape.isEmpty())
@@ -820,22 +814,55 @@ public class LodBuilder
notFullBlock.put(blockState.getBlock(), true);
else
notFullBlock.put(blockState.getBlock(), false);
-
- if (xWidth < 0.7 && zWidth < 0.7 && yWidth < 0.7)
- smallBlock.put(blockState.getBlock(), true);
- else
- smallBlock.put(blockState.getBlock(), false);
}
else
{
notFullBlock.put(blockState.getBlock(), false);
- smallBlock.put(blockState.getBlock(), false);
}
}
- if (notFullBlock.get(blockState.getBlock()) && avoidNonFullBlock)
+ if (notFullBlock.get(blockState.getBlock()))
return false;
- if (smallBlock.get(blockState.getBlock()) && avoidSmallBlock)
+ }
+
+ if (avoidBlockWithNoCollision)
+ {
+ if (!smallBlock.containsKey(blockState.getBlock())
+ || smallBlock.get(blockState.getBlock()) == null
+ )
+ {
+ if(!blockState.getFluidState().isEmpty())
+ smallBlock.put(blockState.getBlock(), false);
+
+ VoxelShape voxelShape = blockState.getCollisionShape(chunk, blockPos);
+ if (!blockState.getFluidState().isEmpty())
+ {
+ smallBlock.put(blockState.getBlock(), false);
+ }
+ else
+ {
+
+ if (voxelShape.isEmpty())
+ {
+ smallBlock.put(blockState.getBlock(), true);
+ /*AxisAlignedBB bbox = voxelShape.bounds();
+ int xWidth = (int) (bbox.maxX - bbox.minX);
+ int yWidth = (int) (bbox.maxY - bbox.minY);
+ int zWidth = (int) (bbox.maxZ - bbox.minZ);
+
+ if (xWidth < 0.7 && zWidth < 0.7 && yWidth < 0.7)
+ smallBlock.put(blockState.getBlock(), true);
+ else
+ smallBlock.put(blockState.getBlock(), false);*/
+ }
+ else
+ {
+ smallBlock.put(blockState.getBlock(), false);
+ }
+ }
+ }
+
+ if (smallBlock.get(blockState.getBlock()))
return false;
}
diff --git a/src/main/java/com/seibel/lod/config/LodConfig.java b/src/main/java/com/seibel/lod/config/LodConfig.java
index 6cae3b764..a6938d688 100644
--- a/src/main/java/com/seibel/lod/config/LodConfig.java
+++ b/src/main/java/com/seibel/lod/config/LodConfig.java
@@ -108,95 +108,95 @@ public class LodConfig
builder.comment("These settings control how the LODs look.").push(this.getClass().getSimpleName());
drawLods = builder
- .comment("\n\n"
- + " If true, the mod is enabled and LODs will be drawn. \n"
- + " If false, the mod will still generate LODs, \n"
- + " but they won't be rendered. \n")
- .define("drawLODs", true);
+ .comment("\n\n"
+ + " If true, the mod is enabled and LODs will be drawn. \n"
+ + " If false, the mod will still generate LODs, \n"
+ + " but they won't be rendered. \n")
+ .define("drawLODs", true);
fogDistance = builder
- .comment("\n\n"
- + " At what distance should Fog be drawn on the LODs? \n"
- + " If the fog cuts off abruptly or you are using Optifine's \"fast\" fog option \n"
- + " set this to " + FogDistance.NEAR + " or " + FogDistance.FAR + ". \n")
- .defineEnum("fogDistance", FogDistance.NEAR_AND_FAR);
+ .comment("\n\n"
+ + " At what distance should Fog be drawn on the LODs? \n"
+ + " If the fog cuts off abruptly or you are using Optifine's \"fast\" fog option \n"
+ + " set this to " + FogDistance.NEAR + " or " + FogDistance.FAR + ". \n")
+ .defineEnum("fogDistance", FogDistance.NEAR_AND_FAR);
fogDrawOverride = builder
- .comment("\n\n"
- + " When should fog be drawn? \n"
- + " " + FogDrawOverride.USE_OPTIFINE_FOG_SETTING + ": Use whatever Fog setting Optifine is using. If Optifine isn't installed this defaults to " + FogDrawOverride.ALWAYS_DRAW_FOG_FANCY + ". \n"
- + " " + FogDrawOverride.NEVER_DRAW_FOG + ": Never draw fog on the LODs \n"
- + " " + FogDrawOverride.ALWAYS_DRAW_FOG_FAST + ": Always draw fast fog on the LODs \n"
- + " " + FogDrawOverride.ALWAYS_DRAW_FOG_FANCY + ": Always draw fancy fog on the LODs (if your graphics card supports it) \n")
- .defineEnum("fogDrawOverride", FogDrawOverride.ALWAYS_DRAW_FOG_FANCY);
+ .comment("\n\n"
+ + " When should fog be drawn? \n"
+ + " " + FogDrawOverride.USE_OPTIFINE_FOG_SETTING + ": Use whatever Fog setting Optifine is using. If Optifine isn't installed this defaults to " + FogDrawOverride.ALWAYS_DRAW_FOG_FANCY + ". \n"
+ + " " + FogDrawOverride.NEVER_DRAW_FOG + ": Never draw fog on the LODs \n"
+ + " " + FogDrawOverride.ALWAYS_DRAW_FOG_FAST + ": Always draw fast fog on the LODs \n"
+ + " " + FogDrawOverride.ALWAYS_DRAW_FOG_FANCY + ": Always draw fancy fog on the LODs (if your graphics card supports it) \n")
+ .defineEnum("fogDrawOverride", FogDrawOverride.ALWAYS_DRAW_FOG_FANCY);
lodTemplate = builder
- .comment("\n\n"
- + " How should the LODs be drawn? \n"
- + " NOTE: Currently only " + LodTemplate.CUBIC + " is implemented! \n"
- + " \n"
- + " " + LodTemplate.CUBIC + ": LOD Chunks are drawn as rectangular prisms (boxes). \n"
- + " " + LodTemplate.TRIANGULAR + ": LOD Chunks smoothly transition between other. \n"
- + " " + LodTemplate.DYNAMIC + ": LOD Chunks smoothly transition between each other, \n"
- + " " + " unless a neighboring chunk is at a significantly different height. \n")
- .defineEnum("lodTemplate", LodTemplate.CUBIC);
+ .comment("\n\n"
+ + " How should the LODs be drawn? \n"
+ + " NOTE: Currently only " + LodTemplate.CUBIC + " is implemented! \n"
+ + " \n"
+ + " " + LodTemplate.CUBIC + ": LOD Chunks are drawn as rectangular prisms (boxes). \n"
+ + " " + LodTemplate.TRIANGULAR + ": LOD Chunks smoothly transition between other. \n"
+ + " " + LodTemplate.DYNAMIC + ": LOD Chunks smoothly transition between each other, \n"
+ + " " + " unless a neighboring chunk is at a significantly different height. \n")
+ .defineEnum("lodTemplate", LodTemplate.CUBIC);
detailDropOff = builder
- .comment("\n\n"
- + " How smooth should the detail transition for LODs be? \n"
- + DetailDropOff.FANCY + ": quality is determined per-chunk (best quality option, may cause stuttering when moving)\n"
- + DetailDropOff.FAST + ": quality is determined per-region \n")
- .defineEnum("detailDropOff", DetailDropOff.FANCY);
+ .comment("\n\n"
+ + " How smooth should the detail transition for LODs be? \n"
+ + DetailDropOff.FANCY + ": quality is determined per-chunk (best quality option, may cause stuttering when moving)\n"
+ + DetailDropOff.FAST + ": quality is determined per-region \n")
+ .defineEnum("detailDropOff", DetailDropOff.FANCY);
drawResolution = builder
- .comment("\n\n"
- + " What is the maximum detail LODs should be drawn at? \n"
- + " " + HorizontalResolution.CHUNK + ": render 1 LOD for each Chunk. \n"
- + " " + HorizontalResolution.HALF_CHUNK + ": render 4 LODs for each Chunk. \n"
- + " " + HorizontalResolution.FOUR_BLOCKS + ": render 16 LODs for each Chunk. \n"
- + " " + HorizontalResolution.TWO_BLOCKS + ": render 64 LODs for each Chunk. \n"
- + " " + HorizontalResolution.BLOCK + ": render 256 LODs for each Chunk. \n")
- .defineEnum("Draw resolution", HorizontalResolution.BLOCK);
+ .comment("\n\n"
+ + " What is the maximum detail LODs should be drawn at? \n"
+ + " " + HorizontalResolution.CHUNK + ": render 1 LOD for each Chunk. \n"
+ + " " + HorizontalResolution.HALF_CHUNK + ": render 4 LODs for each Chunk. \n"
+ + " " + HorizontalResolution.FOUR_BLOCKS + ": render 16 LODs for each Chunk. \n"
+ + " " + HorizontalResolution.TWO_BLOCKS + ": render 64 LODs for each Chunk. \n"
+ + " " + HorizontalResolution.BLOCK + ": render 256 LODs for each Chunk. \n")
+ .defineEnum("Draw resolution", HorizontalResolution.BLOCK);
lodChunkRenderDistance = builder
- .comment("\n\n"
- + " The mod's render distance, measured in chunks. \n")
- .defineInRange("lodChunkRenderDistance", 64, 32, 1024);
+ .comment("\n\n"
+ + " The mod's render distance, measured in chunks. \n")
+ .defineInRange("lodChunkRenderDistance", 64, 32, 1024);
disableDirectionalCulling = builder
- .comment("\n\n"
- + " If false LODs that are behind the player's camera \n"
- + " aren't drawn, increasing performance. \n\n"
- + ""
- + " If true all LODs are drawn, even those behind \n"
- + " the player's camera, decreasing performance. \n\n"
- + ""
- + " Disable this if you see LODs disappearing. \n"
- + " (Which may happen if you are using a camera mod) \n")
- .define("disableDirectionalCulling", false);
+ .comment("\n\n"
+ + " If false LODs that are behind the player's camera \n"
+ + " aren't drawn, increasing performance. \n\n"
+ + ""
+ + " If true all LODs are drawn, even those behind \n"
+ + " the player's camera, decreasing performance. \n\n"
+ + ""
+ + " Disable this if you see LODs disappearing. \n"
+ + " (Which may happen if you are using a camera mod) \n")
+ .define("disableDirectionalCulling", false);
alwaysDrawAtMaxQuality = builder
- .comment("\n\n"
- + " Disable LOD quality falloff, \n"
- + " all LODs will be drawn at the highest \n"
- + " available detail level. \n\n"
- + " "
- + " WARNING: \n"
- + " This could cause a Out Of Memory crash on render \n"
- + " distances higher than 128 \n")
- .define("alwaysDrawAtMaxQuality", false);
+ .comment("\n\n"
+ + " Disable LOD quality falloff, \n"
+ + " all LODs will be drawn at the highest \n"
+ + " available detail level. \n\n"
+ + " "
+ + " WARNING: \n"
+ + " This could cause a Out Of Memory crash on render \n"
+ + " distances higher than 128 \n")
+ .define("alwaysDrawAtMaxQuality", false);
vanillaOverdraw = builder
- .comment("\n\n"
- + " How often should LODs be drawn on top of regular chunks? \n"
- + " HALF and ALWAYS will prevent holes in the world, but may look odd for transparent blocks or in caves. \n\n"
- + " " + VanillaOverdraw.NEVER + ": LODs won't render on top of vanilla chunks. \n"
- + " " + VanillaOverdraw.DYNAMIC + ": LODs will render on top of distant vanilla chunks to hide delayed loading. \n"
- + " " + " More effective on higher render distances. \n"
- + " " + " For vanilla render distances less than or equal to " + LodUtil.MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW + " \n"
- + " " + " " + VanillaOverdraw.NEVER + " or " + VanillaOverdraw.ALWAYS + " may be used depending on the dimension. \n"
- + " " + VanillaOverdraw.ALWAYS + ": LODs will render on all vanilla chunks preventing holes in the world. \n")
- .defineEnum("vanillaOverdraw", VanillaOverdraw.DYNAMIC);
+ .comment("\n\n"
+ + " How often should LODs be drawn on top of regular chunks? \n"
+ + " HALF and ALWAYS will prevent holes in the world, but may look odd for transparent blocks or in caves. \n\n"
+ + " " + VanillaOverdraw.NEVER + ": LODs won't render on top of vanilla chunks. \n"
+ + " " + VanillaOverdraw.DYNAMIC + ": LODs will render on top of distant vanilla chunks to hide delayed loading. \n"
+ + " " + " More effective on higher render distances. \n"
+ + " " + " For vanilla render distances less than or equal to " + LodUtil.MINIMUM_RENDER_DISTANCE_FOR_PARTIAL_OVERDRAW + " \n"
+ + " " + " " + VanillaOverdraw.NEVER + " or " + VanillaOverdraw.ALWAYS + " may be used depending on the dimension. \n"
+ + " " + VanillaOverdraw.ALWAYS + ": LODs will render on all vanilla chunks preventing holes in the world. \n")
+ .defineEnum("vanillaOverdraw", VanillaOverdraw.DYNAMIC);
builder.pop();
}
@@ -211,126 +211,141 @@ public class LodConfig
public final ForgeConfigSpec.BooleanValue allowUnstableFeatureGeneration;
public final ForgeConfigSpec.EnumValue horizontalScale;
public final ForgeConfigSpec.EnumValue horizontalQuality;
+ public final ForgeConfigSpec.BooleanValue avoidBlockWithNoCollision;
+ public final ForgeConfigSpec.BooleanValue avoidNonFullBlock;
WorldGenerator(ForgeConfigSpec.Builder builder)
{
builder.comment("These settings control how LODs outside your normal view range are generated.").push(this.getClass().getSimpleName());
verticalQuality = builder
- .comment("\n\n"
- + " This indicates how detailed the LODs will be in representing \n"
- + " overhangs, caves, floating islands, ect. \n"
- + " Higher options will use more memory and lower performance. \n"
- + " " + VerticalQuality.LOW + ": uses at max 2 columns per position. \n"
- + " " + VerticalQuality.HIGH + ": uses at max 8 columns per position. \n")
- .defineEnum("Vertical Quality", VerticalQuality.MEDIUM);
+ .comment("\n\n"
+ + " This indicates how detailed the LODs will be in representing \n"
+ + " overhangs, caves, floating islands, ect. \n"
+ + " Higher options will use more memory and lower performance. \n"
+ + " " + VerticalQuality.LOW + ": uses at max 2 columns per position. \n"
+ + " " + VerticalQuality.HIGH + ": uses at max 8 columns per position. \n")
+ .defineEnum("Vertical Quality", VerticalQuality.MEDIUM);
+
+
generationResolution = builder
- .comment("\n\n"
- + " What is the maximum detail level that LODs should be generated at? \n"
- + " " + HorizontalResolution.CHUNK + ": render 1 LOD for each Chunk. \n"
- + " " + HorizontalResolution.HALF_CHUNK + ": render 4 LODs for each Chunk. \n"
- + " " + HorizontalResolution.FOUR_BLOCKS + ": render 16 LODs for each Chunk. \n"
- + " " + HorizontalResolution.TWO_BLOCKS + ": render 64 LODs for each Chunk. \n"
- + " " + HorizontalResolution.BLOCK + ": render 256 LODs for each Chunk. \n")
- .defineEnum("Generation Resolution", HorizontalResolution.BLOCK);
+ .comment("\n\n"
+ + " What is the maximum detail level that LODs should be generated at? \n"
+ + " " + HorizontalResolution.CHUNK + ": render 1 LOD for each Chunk. \n"
+ + " " + HorizontalResolution.HALF_CHUNK + ": render 4 LODs for each Chunk. \n"
+ + " " + HorizontalResolution.FOUR_BLOCKS + ": render 16 LODs for each Chunk. \n"
+ + " " + HorizontalResolution.TWO_BLOCKS + ": render 64 LODs for each Chunk. \n"
+ + " " + HorizontalResolution.BLOCK + ": render 256 LODs for each Chunk. \n")
+ .defineEnum("Generation Resolution", HorizontalResolution.BLOCK);
horizontalScale = builder
- .comment("\n\n"
- + " This indicates how quickly LODs drop off in quality. \n"
- + " " + HorizontalScale.LOW + ": quality drops every " + HorizontalScale.LOW.distanceUnit / 16 + " chunks. \n"
- + " " + HorizontalScale.MEDIUM + ": quality drops every " + HorizontalScale.MEDIUM.distanceUnit / 16 + " chunks. \n"
- + " " + HorizontalScale.HIGH + ": quality drops every " + HorizontalScale.HIGH.distanceUnit / 16 + " chunks. \n")
- .defineEnum("horizontal scale", HorizontalScale.MEDIUM);
+ .comment("\n\n"
+ + " This indicates how quickly LODs drop off in quality. \n"
+ + " " + HorizontalScale.LOW + ": quality drops every " + HorizontalScale.LOW.distanceUnit / 16 + " chunks. \n"
+ + " " + HorizontalScale.MEDIUM + ": quality drops every " + HorizontalScale.MEDIUM.distanceUnit / 16 + " chunks. \n"
+ + " " + HorizontalScale.HIGH + ": quality drops every " + HorizontalScale.HIGH.distanceUnit / 16 + " chunks. \n")
+ .defineEnum("horizontal scale", HorizontalScale.MEDIUM);
horizontalQuality = builder
- .comment("\n\n"
- + " This indicates the exponential base of the quadratic drop-off \n"
- + " " + HorizontalQuality.LINEAR + ": base " + HorizontalQuality.LINEAR.quadraticBase + ". \n"
- + " " + HorizontalQuality.LOW + ": base " + HorizontalQuality.LOW.quadraticBase + ". \n"
- + " " + HorizontalQuality.MEDIUM + ": base " + HorizontalQuality.MEDIUM.quadraticBase + ". \n"
- + " " + HorizontalQuality.HIGH + ": base " + HorizontalQuality.HIGH.quadraticBase + ". \n")
- .defineEnum("horizontal quality", HorizontalQuality.MEDIUM);
+ .comment("\n\n"
+ + " This indicates the exponential base of the quadratic drop-off \n"
+ + " " + HorizontalQuality.LINEAR + ": base " + HorizontalQuality.LINEAR.quadraticBase + ". \n"
+ + " " + HorizontalQuality.LOW + ": base " + HorizontalQuality.LOW.quadraticBase + ". \n"
+ + " " + HorizontalQuality.MEDIUM + ": base " + HorizontalQuality.MEDIUM.quadraticBase + ". \n"
+ + " " + HorizontalQuality.HIGH + ": base " + HorizontalQuality.HIGH.quadraticBase + ". \n")
+ .defineEnum("horizontal quality", HorizontalQuality.MEDIUM);
generationPriority = builder
- .comment("\n\n"
- + " " + GenerationPriority.FAR_FIRST + " \n"
- + " LODs are generated from low to high detail \n"
- + " with a small priority for far away regions. \n"
- + " This fills in the world fastest. \n\n"
- + ""
- + " " + GenerationPriority.NEAR_FIRST + " \n"
- + " LODs are generated around the player \n"
- + " in a spiral, similar to vanilla minecraft. \n")
- .defineEnum("Generation priority", GenerationPriority.NEAR_FIRST);
+ .comment("\n\n"
+ + " " + GenerationPriority.FAR_FIRST + " \n"
+ + " LODs are generated from low to high detail \n"
+ + " with a small priority for far away regions. \n"
+ + " This fills in the world fastest. \n\n"
+ + ""
+ + " " + GenerationPriority.NEAR_FIRST + " \n"
+ + " LODs are generated around the player \n"
+ + " in a spiral, similar to vanilla minecraft. \n")
+ .defineEnum("Generation priority", GenerationPriority.NEAR_FIRST);
distanceGenerationMode = builder
- .comment("\n\n"
- + " Note: The times listed here are the amount of time it took \n"
- + " one of the developer's PC to generate 1 chunk, \n"
- + " and are included so you can compare the \n"
- + " different generation options. Your mileage may vary. \n"
- + "\n"
+ .comment("\n\n"
+ + " Note: The times listed here are the amount of time it took \n"
+ + " one of the developer's PC to generate 1 chunk, \n"
+ + " and are included so you can compare the \n"
+ + " different generation options. Your mileage may vary. \n"
+ + "\n"
- + " " + DistanceGenerationMode.NONE + " \n"
- + " Don't run the distance generator. \n"
+ + " " + DistanceGenerationMode.NONE + " \n"
+ + " Don't run the distance generator. \n"
- + "\n"
- + " " + DistanceGenerationMode.BIOME_ONLY + " \n"
- + " Only generate the biomes and use the biome's \n"
- + " grass color, water color, or snow color. \n"
- + " Doesn't generate height, everything is shown at sea level. \n"
- + " Multithreaded - Fastest (2-5 ms) \n"
+ + "\n"
+ + " " + DistanceGenerationMode.BIOME_ONLY + " \n"
+ + " Only generate the biomes and use the biome's \n"
+ + " grass color, water color, or snow color. \n"
+ + " Doesn't generate height, everything is shown at sea level. \n"
+ + " Multithreaded - Fastest (2-5 ms) \n"
- + "\n"
- + " " + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT + " \n"
- + " Same as BIOME_ONLY, except instead \n"
- + " of always using sea level as the LOD height \n"
- + " different biome types (mountain, ocean, forest, etc.) \n"
- + " use predetermined heights to simulate having height data. \n"
- + " Multithreaded - Fastest (2-5 ms) \n"
+ + "\n"
+ + " " + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT + " \n"
+ + " Same as BIOME_ONLY, except instead \n"
+ + " of always using sea level as the LOD height \n"
+ + " different biome types (mountain, ocean, forest, etc.) \n"
+ + " use predetermined heights to simulate having height data. \n"
+ + " Multithreaded - Fastest (2-5 ms) \n"
- + "\n"
- + " " + DistanceGenerationMode.SURFACE + " \n"
- + " Generate the world surface, \n"
- + " this does NOT include trees, \n"
- + " or structures. \n"
- + " Multithreaded - Faster (10-20 ms) \n"
+ + "\n"
+ + " " + DistanceGenerationMode.SURFACE + " \n"
+ + " Generate the world surface, \n"
+ + " this does NOT include trees, \n"
+ + " or structures. \n"
+ + " Multithreaded - Faster (10-20 ms) \n"
- + "\n"
- + " " + DistanceGenerationMode.FEATURES + " \n"
- + " Generate everything except structures. \n"
- + " WARNING: This may cause world generation bugs or instability! \n"
- + " Multithreaded - Fast (15-20 ms) \n"
+ + "\n"
+ + " " + DistanceGenerationMode.FEATURES + " \n"
+ + " Generate everything except structures. \n"
+ + " WARNING: This may cause world generation bugs or instability! \n"
+ + " Multithreaded - Fast (15-20 ms) \n"
- + "\n"
- + " " + DistanceGenerationMode.SERVER + " \n"
- + " Ask the server to generate/load each chunk. \n"
- + " This will show player made structures, which can \n"
- + " be useful if you are adding the mod to a pre-existing world. \n"
- + " This is the most compatible, but causes server/simulation lag. \n"
- + " SingleThreaded - Slow (15-50 ms, with spikes up to 200 ms) \n")
- .defineEnum("distanceGenerationMode", DistanceGenerationMode.SURFACE);
+ + "\n"
+ + " " + DistanceGenerationMode.SERVER + " \n"
+ + " Ask the server to generate/load each chunk. \n"
+ + " This will show player made structures, which can \n"
+ + " be useful if you are adding the mod to a pre-existing world. \n"
+ + " This is the most compatible, but causes server/simulation lag. \n"
+ + " SingleThreaded - Slow (15-50 ms, with spikes up to 200 ms) \n")
+ .defineEnum("distanceGenerationMode", DistanceGenerationMode.SURFACE);
allowUnstableFeatureGeneration = builder
- .comment("\n\n"
- + " When using the " + DistanceGenerationMode.FEATURES + " generation mode \n"
- + " some features may not be thread safe, which could \n"
- + " cause instability and crashes. \n"
- + " By default (false) those features are skipped, \n"
- + " improving stability, but decreasing how many features are \n"
- + " actually generated. \n"
- + " (for example: some tree generation is unstable, \n"
- + " so some trees may not be generated.) \n"
- + " By setting this to true, all features will be generated, \n"
- + " but your game will be more unstable and crashes may occur. \n"
- + " \n"
- + " I would love to remove this option and always generate everything, \n"
- + " but I'm not sure how to do that. \n"
- + " If you are a Java wizard, check out the git issue here: \n"
- + " https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/35 \n")
- .define("allowUnstableFeatureGeneration", false);
+ .comment("\n\n"
+ + " When using the " + DistanceGenerationMode.FEATURES + " generation mode \n"
+ + " some features may not be thread safe, which could \n"
+ + " cause instability and crashes. \n"
+ + " By default (false) those features are skipped, \n"
+ + " improving stability, but decreasing how many features are \n"
+ + " actually generated. \n"
+ + " (for example: some tree generation is unstable, \n"
+ + " so some trees may not be generated.) \n"
+ + " By setting this to true, all features will be generated, \n"
+ + " but your game will be more unstable and crashes may occur. \n"
+ + " \n"
+ + " I would love to remove this option and always generate everything, \n"
+ + " but I'm not sure how to do that. \n"
+ + " If you are a Java wizard, check out the git issue here: \n"
+ + " https://gitlab.com/jeseibel/minecraft-lod-mod/-/issues/35 \n")
+ .define("allowUnstableFeatureGeneration", false);
+ avoidBlockWithNoCollision = builder
+ .comment("\n\n"
+ + " if true avoid block that have no collision box in the generation \n"
+ + " grass, \n")
+ .define("avoid Block With No Collision", false);
+
+ avoidNonFullBlock = builder
+ .comment("\n\n"
+ + " If you are a Java wizard, check out the git issue here: \n"
+ + " If you are a Java wizard, check out the git issue here: \n")
+ .define("avoid Non Full Block", false);
builder.pop();
}
}
@@ -345,27 +360,27 @@ public class LodConfig
builder.comment("These settings control how many CPU threads the mod uses for different tasks.").push(this.getClass().getSimpleName());
numberOfWorldGenerationThreads = builder
- .comment("\n\n"
- + " This is how many threads are used when generating LODs outside \n"
- + " the normal render distance. \n"
- + " If you experience stuttering when generating distant LODs, decrease \n"
- + " this number. If you want to increase LOD generation speed, \n"
- + " increase this number. \n"
- + " \n"
- + " The maximum value is the number of logical processors on your CPU. \n"
- + " Requires a restart to take effect. \n")
- .defineInRange("numberOfWorldGenerationThreads", Runtime.getRuntime().availableProcessors() / 2, 1, Runtime.getRuntime().availableProcessors());
+ .comment("\n\n"
+ + " This is how many threads are used when generating LODs outside \n"
+ + " the normal render distance. \n"
+ + " If you experience stuttering when generating distant LODs, decrease \n"
+ + " this number. If you want to increase LOD generation speed, \n"
+ + " increase this number. \n"
+ + " \n"
+ + " The maximum value is the number of logical processors on your CPU. \n"
+ + " Requires a restart to take effect. \n")
+ .defineInRange("numberOfWorldGenerationThreads", Runtime.getRuntime().availableProcessors() / 2, 1, Runtime.getRuntime().availableProcessors());
numberOfBufferBuilderThreads = builder
- .comment("\n\n"
- + " This is how many threads are used when building vertex buffers \n"
- + " (The things sent to your GPU to draw the LODs). \n"
- + " If you experience high CPU usage when NOT generating distant \n"
- + " LODs, lower this number. \n"
- + " \n"
- + " The maximum value is the number of logical processors on your CPU. \n"
- + " Requires a restart to take effect. \n")
- .defineInRange("numberOfBufferBuilderThreads", Runtime.getRuntime().availableProcessors(), 1, Runtime.getRuntime().availableProcessors());
+ .comment("\n\n"
+ + " This is how many threads are used when building vertex buffers \n"
+ + " (The things sent to your GPU to draw the LODs). \n"
+ + " If you experience high CPU usage when NOT generating distant \n"
+ + " LODs, lower this number. \n"
+ + " \n"
+ + " The maximum value is the number of logical processors on your CPU. \n"
+ + " Requires a restart to take effect. \n")
+ .defineInRange("numberOfBufferBuilderThreads", Runtime.getRuntime().availableProcessors(), 1, Runtime.getRuntime().availableProcessors());
builder.pop();
}
@@ -381,17 +396,17 @@ public class LodConfig
builder.comment("These settings can be used to look for bugs, or see how certain aspects of the mod work.").push(this.getClass().getSimpleName());
debugMode = builder
- .comment("\n\n"
- + " " + DebugMode.OFF + ": LODs will draw with their normal colors. \n"
- + " " + DebugMode.SHOW_DETAIL + ": LOD colors will be based on their detail level. \n"
- + " " + DebugMode.SHOW_DETAIL_WIREFRAME + ": LOD colors will be based on their detail level, drawn as a wireframe. \n")
- .defineEnum("debugMode", DebugMode.OFF);
+ .comment("\n\n"
+ + " " + DebugMode.OFF + ": LODs will draw with their normal colors. \n"
+ + " " + DebugMode.SHOW_DETAIL + ": LOD colors will be based on their detail level. \n"
+ + " " + DebugMode.SHOW_DETAIL_WIREFRAME + ": LOD colors will be based on their detail level, drawn as a wireframe. \n")
+ .defineEnum("debugMode", DebugMode.OFF);
enableDebugKeybindings = builder
- .comment("\n\n"
- + " If true the F4 key can be used to cycle through the different debug modes. \n"
- + " and the F6 key can be used to enable and disable LOD rendering.")
- .define("enableDebugKeybinding", false);
+ .comment("\n\n"
+ + " If true the F4 key can be used to cycle through the different debug modes. \n"
+ + " and the F6 key can be used to enable and disable LOD rendering.")
+ .define("enableDebugKeybinding", false);
builder.pop();
}
@@ -406,10 +421,10 @@ public class LodConfig
builder.comment("These settings affect when Vertex Buffers are built.").push(this.getClass().getSimpleName());
rebuildTimes = builder
- .comment("\n\n"
- + " How frequently should geometry be rebuilt and sent to the GPU? \n"
- + " Faster settings may cause stuttering, but will prevent holes in the world \n")
- .defineEnum("rebuildFrequency", BufferRebuildTimes.NORMAL);
+ .comment("\n\n"
+ + " How frequently should geometry be rebuilt and sent to the GPU? \n"
+ + " Faster settings may cause stuttering, but will prevent holes in the world \n")
+ .defineEnum("rebuildFrequency", BufferRebuildTimes.NORMAL);
builder.pop();
}
@@ -429,8 +444,8 @@ public class LodConfig
CLIENT_SPEC = specPair.getRight();
CLIENT = specPair.getLeft();
CommentedFileConfig clientConfig = CommentedFileConfig.builder(CONFIG_PATH)
- .writingMode(WritingMode.REPLACE)
- .build();
+ .writingMode(WritingMode.REPLACE)
+ .build();
clientConfig.load();
clientConfig.save();
CLIENT_SPEC.setConfig(clientConfig);
diff --git a/src/main/java/com/seibel/lod/objects/LevelContainer.java b/src/main/java/com/seibel/lod/objects/LevelContainer.java
index 0d1c83820..9ba605086 100644
--- a/src/main/java/com/seibel/lod/objects/LevelContainer.java
+++ b/src/main/java/com/seibel/lod/objects/LevelContainer.java
@@ -1,5 +1,8 @@
package com.seibel.lod.objects;
+/**
+ * A level container is a quad tree level
+ */
public interface LevelContainer
{
/**With this you can add data to the level container
@@ -81,10 +84,4 @@ public interface LevelContainer
* @return data as a String
*/
int getMaxNumberOfLods();
-
- /**
- * This will give the data to save in the file
- * @return data as a String
- */
- int getMaxMemoryUse();
}
diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java
index 94ac415d2..dd01a9186 100644
--- a/src/main/java/com/seibel/lod/objects/LodRegion.java
+++ b/src/main/java/com/seibel/lod/objects/LodRegion.java
@@ -10,7 +10,7 @@ import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
/**
- * This object holds all loaded LevelContainers
+ * This object holds all loaded LevelContainers acting as a quad tree
* for a given region.
*
* Coordinate Standard:
@@ -500,7 +500,7 @@ public class LodRegion
for (byte detailLevelIndex = (byte) (minDetailLevel - 1); detailLevelIndex >= detailLevel; detailLevelIndex--)
{
if (dataContainer[detailLevelIndex + 1] == null)
- dataContainer[detailLevelIndex + 1] = new SingleLevelContainer((byte) (detailLevelIndex + 1));
+ dataContainer[detailLevelIndex + 1] = new VerticalLevelContainer((byte) (detailLevelIndex + 1));
dataContainer[detailLevelIndex] = dataContainer[detailLevelIndex + 1].expand();
}
diff --git a/src/main/java/com/seibel/lod/objects/SingleLevelContainer.java b/src/main/java/com/seibel/lod/objects/SingleLevelContainer.java
deleted file mode 100644
index 8ce158e1e..000000000
--- a/src/main/java/com/seibel/lod/objects/SingleLevelContainer.java
+++ /dev/null
@@ -1,233 +0,0 @@
-package com.seibel.lod.objects;
-
-import com.seibel.lod.util.DataPointUtil;
-import com.seibel.lod.util.LevelPosUtil;
-import com.seibel.lod.util.LodUtil;
-import com.seibel.lod.util.ThreadMapUtil;
-
-import java.util.Arrays;
-
-/**
- * This object holds the LOD data for a single dataPoint.
- *
- * @author Leonardo Amato
- * @version 9-28-2021
- */
-public class SingleLevelContainer implements LevelContainer
-{
- /** The detailLevel of this LevelContainer */
- public final byte detailLevel;
- /** How many dataPoints wide is this LevelContainer? */
- public final int dataWidthCount;
-
- /** This holds all the dataPoints for this LevelContainer */
- public final long[][] dataContainer;
-
-
-
- /** Constructor */
- public SingleLevelContainer(byte newDetailLevel)
- {
- this.detailLevel = newDetailLevel;
-
- // equivalent to 2^(...)
- dataWidthCount = 1 << (LodUtil.REGION_DETAIL_LEVEL - newDetailLevel);
- dataContainer = new long[dataWidthCount][dataWidthCount];
- }
-
- /** */
- public SingleLevelContainer(byte[] inputData)
- {
- int tempIndex;
- int index = 0;
- long newData;
- detailLevel = inputData[index];
- index++;
- dataWidthCount = (int) Math.pow(2, LodUtil.REGION_DETAIL_LEVEL - detailLevel);
- this.dataContainer = new long[dataWidthCount][dataWidthCount];
-
- for (int x = 0; x < dataWidthCount; x++)
- {
- for (int z = 0; z < dataWidthCount; z++)
- {
- newData = 0;
- if (inputData[index] == 0)
- {
- index++;
- }
- else if (inputData[index] == 3)
- {
- newData = 3;
- index++;
- }
- else if (index + 7 >= inputData.length)
- {
- break;
- }
- else
- {
- for (tempIndex = 0; tempIndex < 8; tempIndex++)
- newData += (((long) inputData[index + tempIndex]) & 0xff) << (8 * tempIndex);
- index = index + 8;
- }
-
- dataContainer[x][z] = newData;
- }
- }
- }
-
-
-
-
-
- @Override
- public void clear(int posX, int posZ)
- {
- posX = LevelPosUtil.getRegionModule(detailLevel, posX);
- posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
- dataContainer[posX][posZ] = DataPointUtil.EMPTY_DATA;
- }
-
- @Override
- public boolean addData(long data, int posX, int posZ, int index)
- {
- posX = LevelPosUtil.getRegionModule(detailLevel, posX);
- posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
- dataContainer[posX][posZ] = data;
- return true;
- }
-
- @Override
- public boolean addSingleData(long newData, int posX, int posZ)
- {
- posX = LevelPosUtil.getRegionModule(detailLevel, posX);
- posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
- dataContainer[posX][posZ] = newData;
- return true;
- }
-
- @Override
- public long getData(int posX, int posZ, int index)
- {
- posX = LevelPosUtil.getRegionModule(detailLevel, posX);
- posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
- // TODO Improve this using a thread map to long[]
- return dataContainer[posX][posZ];
- }
-
- @Override
- public long getSingleData(int posX, int posZ)
- {
- posX = LevelPosUtil.getRegionModule(detailLevel, posX);
- posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
- // TODO Improve this using a thread map to long[]
- return dataContainer[posX][posZ];
- }
-
- @Override
- public byte getDetailLevel()
- {
- return detailLevel;
- }
-
- @Override
- public LevelContainer expand()
- {
- return new SingleLevelContainer((byte) (getDetailLevel() - 1));
- }
-
-
-
- /** TODO could this be renamed mergeData? */
- @Override
- public void updateData(LevelContainer lowerLevelContainer, int posX, int posZ)
- {
- //We reset the array
- long[] dataToMerge = ThreadMapUtil.getSingleUpdateArray();
-
- int childPosX;
- int childPosZ;
- long data;
- posX = LevelPosUtil.getRegionModule(detailLevel, posX);
- posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
- for (int x = 0; x <= 1; x++)
- {
- for (int z = 0; z <= 1; z++)
- {
- childPosX = 2 * posX + x;
- childPosZ = 2 * posZ + z;
- dataToMerge[2 * x + z] = lowerLevelContainer.getSingleData(childPosX, childPosZ);
- }
- }
- data = DataPointUtil.mergeSingleData(dataToMerge);
- addSingleData(data, posX, posZ);
- }
-
- @Override
- public int getMaxVerticalData()
- {
- return 1;
- }
-
- @Override
- public boolean doesItExist(int posX, int posZ)
- {
- posX = LevelPosUtil.getRegionModule(detailLevel, posX);
- posZ = LevelPosUtil.getRegionModule(detailLevel, posZ);
- //Improve this using a thread map to long[]
- return DataPointUtil.doesItExist(getSingleData(posX, posZ));
- }
-
- @Override
- public byte[] toDataString()
- {
- int index = 0;
- int tempIndex;
- byte[] tempData = ThreadMapUtil.getSaveContainer(1 + (dataWidthCount * dataWidthCount * 8));
-
- tempData[index] = detailLevel;
- index++;
- for (int x = 0; x < dataWidthCount; x++)
- {
- for (int z = 0; z < dataWidthCount; z++)
- {
- if (dataContainer[x][z] == 0)
- {
- tempData[index] = 0;
- index++;
- }
- else if (dataContainer[x][z] == 3)
- {
- tempData[index] = 3;
- index++;
- }
- else
- {
- for (tempIndex = 0; tempIndex < 8; tempIndex++)
- tempData[index + tempIndex] = (byte) (dataContainer[x][z] >>> (8 * tempIndex));
- index += 8;
- }
- }
- }
- return Arrays.copyOfRange(tempData, 0, index);
- }
-
- @Override
- public String toString()
- {
- return String.valueOf(detailLevel);
- }
-
-
- @Override
- public int getMaxNumberOfLods()
- {
- return dataWidthCount * dataWidthCount * getMaxVerticalData();
- }
-
- @Override
- public int getMaxMemoryUse()
- {
- return getMaxNumberOfLods() * 2; //2 byte
- }
-}
diff --git a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java
index 2526b5523..633cb68e0 100644
--- a/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java
+++ b/src/main/java/com/seibel/lod/objects/VerticalLevelContainer.java
@@ -8,6 +8,9 @@ import com.seibel.lod.util.LevelPosUtil;
import com.seibel.lod.util.LodUtil;
import com.seibel.lod.util.ThreadMapUtil;
+/**
+ * a VerticalLevelContainer is a quadTree level that can contain multiple voxel column per position.
+ */
public class VerticalLevelContainer implements LevelContainer
{
@@ -254,8 +257,4 @@ public class VerticalLevelContainer implements LevelContainer
return size*size*getMaxVerticalData();
}
- @Override
- public int getMaxMemoryUse(){
- return getMaxNumberOfLods() * 2; //2 byte
- }
}