diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index 46100c328..d78d7be81 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -21,8 +21,10 @@ import java.awt.Color; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DistanceGenerationMode; import com.seibel.lod.enums.LodDetail; +import com.seibel.lod.enums.LodQualityMode; import com.seibel.lod.util.*; import com.seibel.lod.objects.LodDimension; import com.seibel.lod.objects.LodRegion; @@ -175,6 +177,7 @@ public class LodBuilder byte minDetailLevel = region.getMinDetailLevel(); detail = DetailDistanceUtil.getLodGenDetail(minDetailLevel); + LodQualityMode lodQualityMode = LodConfig.CLIENT.worldGenerator.lodQualityMode.get(); byte detailLevel = detail.detailLevel; int posX; int posZ; @@ -187,21 +190,25 @@ public class LodBuilder posX = LevelPosUtil.convert((byte) 0, chunk.getPos().x * 16 + startX, detail.detailLevel); posZ = LevelPosUtil.convert((byte) 0, chunk.getPos().z * 16 + startZ, detail.detailLevel); - long[] data; - long[][] dataToMerge; - //data = ThreadMapUtil.getSingleAddDataArray(); - //dataToMerge = createSingleDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); - /*long[][] dataToMerge2 = new long[dataToMerge.length][]; - for (int index = 0; index < dataToMerge.length; index++) - { - dataToMerge2[index] = new long[]{dataToMerge[index]}; - }*/ - //data[0] = DataPointUtil.mergeSingleData(dataToMerge); + long[] data = null + ; + switch (lodQualityMode){ + case HEIGHTMAP: + data = ThreadMapUtil.getSingleAddDataArray(); + long[] dataToMergeSingle; + dataToMergeSingle = createSingleDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); + data[0] = DataPointUtil.mergeSingleData(dataToMergeSingle); + break; + case MULTI_LOD: + long[][] dataToMergeVertical; + dataToMergeVertical = createVerticalDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); + data = DataPointUtil.mergeVerticalData(dataToMergeVertical); + break; + } - dataToMerge = createVerticalDataToMerge(detail, chunk, config, startX, startZ, endX, endZ); - data = DataPointUtil.mergeVerticalData(dataToMerge); if (data.length == 0 || data == null) data = new long[]{DataPointUtil.EMPTY_DATA}; + boolean isServer = config.distanceGenerationMode == DistanceGenerationMode.SERVER; lodDim.addData(detailLevel, posX, diff --git a/src/main/java/com/seibel/lod/config/LodConfig.java b/src/main/java/com/seibel/lod/config/LodConfig.java index 7418c0320..76b1276a8 100644 --- a/src/main/java/com/seibel/lod/config/LodConfig.java +++ b/src/main/java/com/seibel/lod/config/LodConfig.java @@ -20,20 +20,13 @@ package com.seibel.lod.config; import java.nio.file.Path; import java.nio.file.Paths; +import com.seibel.lod.enums.*; import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.io.WritingMode; import com.seibel.lod.ModInfo; -import com.seibel.lod.enums.DebugMode; -import com.seibel.lod.enums.DistanceCalculatorType; -import com.seibel.lod.enums.DistanceGenerationMode; -import com.seibel.lod.enums.FogDistance; -import com.seibel.lod.enums.FogDrawOverride; -import com.seibel.lod.enums.LodDetail; -import com.seibel.lod.enums.LodTemplate; -import com.seibel.lod.enums.ShadingMode; import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -192,6 +185,7 @@ public class LodConfig public static class WorldGenerator { + public ForgeConfigSpec.EnumValue lodQualityMode; public ForgeConfigSpec.EnumValue maxGenerationDetail; public ForgeConfigSpec.EnumValue distanceGenerationMode; public ForgeConfigSpec.BooleanValue allowUnstableFeatureGeneration; @@ -201,7 +195,14 @@ public class LodConfig WorldGenerator(ForgeConfigSpec.Builder builder) { builder.comment("These settings control how LODs outside your normal view range are generated.").push(this.getClass().getSimpleName()); - + + lodQualityMode = builder + .comment("\n\n" + + " Use 3d lods or 2d lods? \n" + + " " + LodQualityMode.HEIGHTMAP.toString() + ": enable 2d lods with heightmap \n" + + " " + LodQualityMode.MULTI_LOD.toString() + ": enable 3d lods with heightmap \n") + .defineEnum("lodGenerationQuality", LodQualityMode.HEIGHTMAP); + maxGenerationDetail = builder .comment("\n\n" + " What is the maximum detail level that LODs should be generated at? \n" diff --git a/src/main/java/com/seibel/lod/enums/LodQualityMode.java b/src/main/java/com/seibel/lod/enums/LodQualityMode.java new file mode 100644 index 000000000..c14625aa0 --- /dev/null +++ b/src/main/java/com/seibel/lod/enums/LodQualityMode.java @@ -0,0 +1,36 @@ +/* + * This file is part of the LOD Mod, licensed under the GNU GPL v3 License. + * + * Copyright (C) 2020 James Seibel + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.seibel.lod.enums; + +/** + * USE_OPTIFINE_FOG_SETTING,
+ * NEVER_DRAW_FOG,
+ * ALWAYS_DRAW_FOG_FAST,
+ * ALWAYS_DRAW_FOG_FANCY
+ * + * @author James Seibel + * @version 7-03-2021 + */ +public enum LodQualityMode +{ + /** Lods are 2D with heightMap */ + HEIGHTMAP, + + /** Lods expand in three dimension */ + MULTI_LOD; +} \ No newline at end of file diff --git a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java index 0df076916..205ca5ef1 100644 --- a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java +++ b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java @@ -28,6 +28,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import com.seibel.lod.enums.DistanceGenerationMode; +import com.seibel.lod.enums.LodQualityMode; import com.seibel.lod.objects.*; import com.seibel.lod.proxy.ClientProxy; import com.seibel.lod.util.LodThreadFactory; @@ -114,14 +115,14 @@ public class LodDimensionFileHandler * Return the LodRegion region at the given coordinates. * (null if the file doesn't exist) */ - public LodRegion loadRegionFromFile(byte detailLevel, RegionPos regionPos, DistanceGenerationMode generationMode) + public LodRegion loadRegionFromFile(byte detailLevel, RegionPos regionPos, DistanceGenerationMode generationMode, LodQualityMode lodQualityMode) { int regionX = regionPos.x; int regionZ = regionPos.z; - LodRegion region = new LodRegion(LodUtil.REGION_DETAIL_LEVEL,regionPos, generationMode); + LodRegion region = new LodRegion(LodUtil.REGION_DETAIL_LEVEL,regionPos, generationMode, lodQualityMode); for (byte tempDetailLevel = LodUtil.REGION_DETAIL_LEVEL; tempDetailLevel >= detailLevel; tempDetailLevel--) { - String fileName = getFileNameAndPathForRegion(regionX, regionZ, generationMode, tempDetailLevel); + String fileName = getFileNameAndPathForRegion(regionX, regionZ, generationMode, tempDetailLevel, lodQualityMode); try { @@ -256,7 +257,7 @@ public class LodDimensionFileHandler int z = region.regionPosZ; for (byte detailLevel = region.getMinDetailLevel(); detailLevel <= LodUtil.REGION_DETAIL_LEVEL; detailLevel++) { - String fileName = getFileNameAndPathForRegion(x, z, region.getGenerationMode(), detailLevel); + String fileName = getFileNameAndPathForRegion(x, z, region.getGenerationMode(), detailLevel, region.getLodQualityMode()); File oldFile = new File(fileName); // if the fileName was null that means the folder is inaccessible @@ -352,7 +353,7 @@ public class LodDimensionFileHandler *

* Returns null if there is an IO Exception. */ - private String getFileNameAndPathForRegion(int regionX, int regionZ, DistanceGenerationMode generationMode, byte detailLevel) + private String getFileNameAndPathForRegion(int regionX, int regionZ, DistanceGenerationMode generationMode, byte detailLevel, LodQualityMode lodQualityMode) { try { @@ -361,6 +362,7 @@ public class LodDimensionFileHandler // or // ".\Super Flat\data" return dimensionDataSaveFolder.getCanonicalPath() + File.separatorChar + + lodQualityMode + File.separatorChar + generationMode.toString() + File.separatorChar + DETAIL_FOLDER_NAME_PREFIX + detailLevel + File.separatorChar + FILE_NAME_PREFIX + "." + regionX + "." + regionZ + FILE_EXTENSION; diff --git a/src/main/java/com/seibel/lod/objects/LodDimension.java b/src/main/java/com/seibel/lod/objects/LodDimension.java index 127d541f7..6c2c3dd46 100644 --- a/src/main/java/com/seibel/lod/objects/LodDimension.java +++ b/src/main/java/com/seibel/lod/objects/LodDimension.java @@ -24,6 +24,7 @@ import java.util.concurrent.Executors; import com.seibel.lod.config.LodConfig; import com.seibel.lod.enums.DistanceGenerationMode; +import com.seibel.lod.enums.LodQualityMode; import com.seibel.lod.handlers.LodDimensionFileHandler; import com.seibel.lod.util.*; import com.seibel.lod.wrappers.MinecraftWrapper; @@ -373,6 +374,7 @@ public class LodDimension { DistanceGenerationMode generationMode = LodConfig.CLIENT.worldGenerator.distanceGenerationMode.get(); ChunkPos newPlayerChunk = new ChunkPos(LevelPosUtil.getChunkPos((byte) 0, playerPosX), LevelPosUtil.getChunkPos((byte) 0, playerPosZ)); + LodQualityMode lodQualityMode = LodConfig.CLIENT.worldGenerator.lodQualityMode.get(); if (lastGenChunk == null) lastGenChunk = new ChunkPos(newPlayerChunk.x + 1, newPlayerChunk.z - 1); @@ -405,12 +407,12 @@ public class LodDimension //First case, region has to be initialized //We check if there is a file at the target level - regions[x][z] = getRegionFromFile(regionPos, levelToGen, generationMode); + regions[x][z] = getRegionFromFile(regionPos, levelToGen, generationMode, lodQualityMode); //if there is no file we initialize the region if (regions[x][z] == null) { - regions[x][z] = new LodRegion(levelToGen, regionPos, generationMode); + regions[x][z] = new LodRegion(levelToGen, regionPos, generationMode, lodQualityMode); } regen[x][z] = true; regenDimension = true; @@ -575,10 +577,10 @@ public class LodDimension * Get the region at the given X and Z coordinates from the * RegionFileHandler. */ - public LodRegion getRegionFromFile(RegionPos regionPos, byte detailLevel, DistanceGenerationMode generationMode) + public LodRegion getRegionFromFile(RegionPos regionPos, byte detailLevel, DistanceGenerationMode generationMode, LodQualityMode lodQualityMode) { if (fileHandler != null) - return fileHandler.loadRegionFromFile(detailLevel, regionPos, generationMode); + return fileHandler.loadRegionFromFile(detailLevel, regionPos, generationMode, lodQualityMode); else return null; } diff --git a/src/main/java/com/seibel/lod/objects/LodRegion.java b/src/main/java/com/seibel/lod/objects/LodRegion.java index b21efdd06..b7ed4040d 100644 --- a/src/main/java/com/seibel/lod/objects/LodRegion.java +++ b/src/main/java/com/seibel/lod/objects/LodRegion.java @@ -3,6 +3,7 @@ package com.seibel.lod.objects; import com.seibel.lod.builders.LodBuilder; import com.seibel.lod.enums.DistanceGenerationMode; +import com.seibel.lod.enums.LodQualityMode; import com.seibel.lod.util.DataPointUtil; import com.seibel.lod.util.DetailDistanceUtil; import com.seibel.lod.util.LevelPosUtil; @@ -31,6 +32,7 @@ public class LodRegion private DistanceGenerationMode generationMode; + private LodQualityMode lodQualityMode; public final int regionPosX; public final int regionPosZ; @@ -43,11 +45,12 @@ public class LodRegion dataContainer = new LevelContainer[POSSIBLE_LOD]; } - public LodRegion(byte minDetailLevel, RegionPos regionPos, DistanceGenerationMode generationMode) + public LodRegion(byte minDetailLevel, RegionPos regionPos, DistanceGenerationMode generationMode, LodQualityMode lodQualityMode) { this.minDetailLevel = minDetailLevel; this.regionPosX = regionPos.x; this.regionPosZ = regionPos.z; + this.lodQualityMode = lodQualityMode; this.generationMode = generationMode; dataContainer = new LevelContainer[POSSIBLE_LOD]; @@ -55,16 +58,20 @@ public class LodRegion //Initialize all the different matrices for (byte lod = minDetailLevel; lod <= LodUtil.REGION_DETAIL_LEVEL; lod++) { - //dataContainer[lod] = new SingleLevelContainer(lod); - dataContainer[lod] = new VerticalLevelContainer(lod); - /*if(twoDimension){ - dataContainer[lod] = new SingleLevelContainer(lod); - }else{ - dataContainer[lod] = new VerticalLevelContainer.java(lod); - }*/ + switch (lodQualityMode){ + case HEIGHTMAP: + dataContainer[lod] = new SingleLevelContainer(lod); + break; + case MULTI_LOD: + dataContainer[lod] = new VerticalLevelContainer(lod); + break; + } } } - + public LodQualityMode getLodQualityMode() + { + return lodQualityMode; + } public DistanceGenerationMode getGenerationMode() { return generationMode; diff --git a/src/main/java/com/seibel/lod/render/RenderUtil.java b/src/main/java/com/seibel/lod/render/RenderUtil.java index 2b9593683..2c474d519 100644 --- a/src/main/java/com/seibel/lod/render/RenderUtil.java +++ b/src/main/java/com/seibel/lod/render/RenderUtil.java @@ -93,7 +93,7 @@ public class RenderUtil { // calculate the max amount of buffer memory needed (in bytes) return LodUtil.REGION_WIDTH_IN_CHUNKS * LodUtil.REGION_WIDTH_IN_CHUNKS * 6 * // TODO this really needs to be more accurate - LodConfig.CLIENT.graphics.lodTemplate.get().getBufferMemoryForSingleLod(); + LodConfig.CLIENT.graphics.lodTemplate.get().getBufferMemoryForSingleLod() * LodUtil.MAX_VERTICAL_DATA; } /** diff --git a/src/main/java/com/seibel/lod/util/LodUtil.java b/src/main/java/com/seibel/lod/util/LodUtil.java index 915eb7bab..833579887 100644 --- a/src/main/java/com/seibel/lod/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/util/LodUtil.java @@ -83,7 +83,9 @@ public class LodUtil public static final byte DETAIL_OPTIONS = 10; - + + public static final short MAX_VERTICAL_DATA = 256; + /** measured in Blocks
* detail level 9 */ public static final short REGION_WIDTH = 512;