diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index 4fe6608b5..2226257f2 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -42,6 +42,8 @@ import net.minecraft.world.chunk.ChunkSection; import net.minecraft.world.chunk.IChunk; import net.minecraft.world.gen.Heightmap; +import javax.xml.crypto.Data; + /** * This object is in charge of creating Lod related objects. (specifically: Lod * World, Dimension, and Region objects) @@ -224,9 +226,7 @@ public class LodBuilder { long[] dataToMerge = ThreadMapUtil.getBuilderArray()[detail.detailLevel]; ChunkPos chunkPos = chunk.getPos(); - BlockState blockState; - ChunkSection[] chunkSections = chunk.getSections(); - ChunkSection section; + int size = 1 << detail.detailLevel; int height = 0; int depth = 0; @@ -235,12 +235,11 @@ public class LodBuilder int generation = config.distanceGenerationMode.complexity; int xRel; - int yRel; int zRel; int xAbs; + int yAbs; int zAbs; - int sectionIndex; - boolean voidData; + BlockPos.Mutable blockPos = new BlockPos.Mutable(0, 0, 0); int index = 0; if (dataToMerge == null) @@ -253,60 +252,24 @@ public class LodBuilder zRel = Math.floorDiv(index, size) + startZ; xAbs = chunkPos.getMinBlockX() + xRel; zAbs = chunkPos.getMinBlockZ() + zRel; - voidData = true; - for (sectionIndex = chunkSections.length - 1; sectionIndex >= 0; sectionIndex--) + + //Calculate the height of the lod + height = determineHeightPoint(chunk, config, xRel, zRel); + + //If the lod is at default, then we set this as void data + if (height == DEFAULT_HEIGHT) { - for (yRel = CHUNK_DATA_WIDTH - 1; yRel >= 0; yRel--) - { - if (isLayerValidLodPoint(chunkSections, sectionIndex, yRel, xRel, zRel)) - { - blockState = chunkSections[sectionIndex].getBlockState(xRel, yRel, zRel); - - height = sectionIndex * CHUNK_DATA_WIDTH + yRel; - Biome biome = chunk.getBiomes().getNoiseBiome(xRel >> 2, yRel + sectionIndex * chunkSections.length >> 2, - zRel >> 2); - color = getColorForBlock(xRel, zRel, blockState, biome); - //color = blockState.getBlock().defaultMaterialColor().col; - - blockPos.set(xAbs, height, zAbs); - light = blockState.getLightBlock(chunk, blockPos); - - voidData = false; - break; - } - } - if (!voidData) - { - break; - } - } - - if (voidData) - { - //no valid block has been found, this column is void dataToMerge[index] = DataPointUtil.createVoidDataPoint(generation); continue; } - //A valid block has been found. Now we search the deepest one + yAbs = height; + blockPos.set(xAbs, yAbs, zAbs); + + color = generateLodColor(chunk, config, xRel, height, zRel); + light = getLightBlockValue(chunk, blockPos, xRel, yAbs, zRel); + depth = determineBottomPoint(chunk, config, xRel, zRel); - voidData = true; - for (sectionIndex = 0; sectionIndex < chunkSections.length; sectionIndex++) - { - for (yRel = 0; yRel < CHUNK_DATA_WIDTH; yRel++) - { - if (isLayerValidLodPoint(chunkSections, sectionIndex, yRel, xRel, zRel)) - { - depth = sectionIndex * CHUNK_DATA_WIDTH + yRel; - voidData = false; - break; - } - } - if (!voidData) - { - break; - } - } dataToMerge[index] = DataPointUtil.createDataPoint(height, depth, color, light, generation); } return dataToMerge; @@ -318,267 +281,110 @@ public class LodBuilder /** * Find the lowest valid point from the bottom. */ - private short determineBottomPointForArea(ChunkSection[] chunkSections, int startX, int startZ, int endX, int endZ) + private short determineBottomPoint(IChunk chunk, LodBuilderConfig config, int xRel, int zRel) { - int numberOfBlocksRequired = ((endX - startX) * (endZ - startZ) / 2); - - // search from the bottom up - for (int section = 0; section < CHUNK_DATA_WIDTH; section++) + ChunkSection[] chunkSections = chunk.getSections(); + short depth = DEFAULT_DEPTH; + if (config.useHeightmap) { - for (int y = 0; y < CHUNK_SECTION_HEIGHT; y++) + depth = 0; + } else + { + boolean found = false; + for (int sectionIndex = 0; sectionIndex < chunkSections.length; sectionIndex++) { - int numberOfBlocksFound = 0; - - for (int x = startX; x < endX; x++) + for (int yRel = 0; yRel < CHUNK_DATA_WIDTH; yRel++) { - for (int z = startZ; z < endZ; z++) + if (isLayerValidLodPoint(chunkSections, sectionIndex, yRel, xRel, zRel)) { - 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)); - } - } + depth = (short) (sectionIndex * CHUNK_DATA_WIDTH + yRel); + found = true; + break; } } + if (found) + { + break; + } } } - - // we never found a valid LOD point - return DEFAULT_DEPTH; + return 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) + private short determineHeightPoint(IChunk chunk, LodBuilderConfig config, int xRel, int zRel) { - int numberOfBlocksRequired = ((endX - startX) * (endZ - startZ) / 2); - // search from the top down - for (int section = chunkSections.length - 1; section >= 0; section--) + short height = DEFAULT_HEIGHT; + if (config.useHeightmap) { - for (int y = CHUNK_DATA_WIDTH - 1; y >= 0; y--) + height = (short) chunk.getOrCreateHeightmapUnprimed(LodUtil.DEFAULT_HEIGHTMAP).getFirstAvailable(xRel, zRel); + } else + { + boolean voidData = true; + ChunkSection[] chunkSections = chunk.getSections(); + for (int sectionIndex = chunkSections.length - 1; sectionIndex >= 0; sectionIndex--) { - int numberOfBlocksFound = 0; - - for (int x = startX; x < endX; x++) + for (int yRel = CHUNK_DATA_WIDTH - 1; yRel >= 0; yRel--) { - for (int z = startZ; z < endZ; z++) + if (isLayerValidLodPoint(chunkSections, sectionIndex, yRel, xRel, zRel)) { - 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)); - } - } + height = (short) (sectionIndex * CHUNK_DATA_WIDTH + yRel); + voidData = false; + break; } } + if (!voidData) + { + break; + } } } - - // 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; + return height; } /** * 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 int generateLodColorForArea(IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX, - int endZ) + private int generateLodColor(IChunk chunk, LodBuilderConfig config, int xRel, int yAbs, int zRel) { ChunkSection[] chunkSections = chunk.getSections(); - - int numbOfBlocks = 0; - int red = 0; - int green = 0; - int blue = 0; - - for (int x = startX; x < endX; x++) + int colorInt = 0; + if (config.useBiomeColors) { - for (int z = startZ; z < endZ; z++) + // 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(xRel >> 2, yAbs >> 2, zRel >> 2); + colorInt = getColorForBiome(xRel, zRel, biome); + } else + { + int sectionIndex = Math.floorDiv(yAbs, CHUNK_SECTION_HEIGHT); + int yRel = Math.floorMod(yAbs, CHUNK_SECTION_HEIGHT); + if (chunkSections[sectionIndex] != null) { - boolean foundBlock = false; + BlockState blockState = chunkSections[sectionIndex].getBlockState(xRel, yRel, zRel); - // 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.getBlock().defaultMaterialColor().col; - } + // the bit shift is equivalent to dividing by 4 + Biome biome = chunk.getBiomes().getNoiseBiome(xRel >> 2, yAbs >> 2, zRel >> 2); - 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; - } - } - } + colorInt = getColorForBlock(xRel, zRel, blockState, biome); } } - - if (numbOfBlocks == 0) - numbOfBlocks = 1; - - red /= numbOfBlocks; - green /= numbOfBlocks; - blue /= numbOfBlocks; - return ColorUtil.rgbToInt(red, green, blue); + return colorInt; } - private byte generateLodLightForArea(IChunk chunk, LodBuilderConfig config, int startX, int startZ, int endX, - int endZ) + private byte getLightBlockValue(IChunk chunk, BlockPos.Mutable blockPos, int xRel, int yAbs, int zRel) { - ChunkSection[] chunkSections = chunk.getSections(); + byte lightBlock; + BlockState blockState = chunk.getSections()[Math.floorDiv(yAbs, CHUNK_SECTION_HEIGHT)].getBlockState(xRel, Math.floorMod(yAbs, CHUNK_SECTION_HEIGHT), zRel); - int numbOfBlocks = 0; - int tempLight; - int light = 0; - BlockPos.Mutable blockPos = new BlockPos.Mutable(0, 0, 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--) - { - tempLight = 0; - BlockState blockState = null; - if (chunkSections[i] != null) - { - blockPos.set(chunk.getPos().getMinBlockX() + x, y, chunk.getPos().getMinBlockZ() + z); - //blockState = chunkSections[i].getBlockState(x, y, z); - - tempLight += MinecraftWrapper.INSTANCE.getPlayer().level.getLightEngine().getLayerListener(LightType.BLOCK).getLightValue(blockPos); - //tempLight += MinecraftWrapper.INSTANCE.getPlayer().level.getLightEngine().blockEngine.getLightValue(blockPos); - //tempLight += blockState.getLightBlock(chunk, blockPos); - } - - - light += tempLight; - - numbOfBlocks++; - - // we found a valid block, skip to the - // next x and z - foundBlock = true; - } - } - } - } - } - - if (numbOfBlocks == 0) - numbOfBlocks = 1; - - light /= numbOfBlocks; - if (light != 0) - { - System.out.println((chunk.getPos().getMinBlockX() + startX) + " " + (chunk.getPos().getMinBlockX() + endX) + " " + (chunk.getPos().getMinBlockZ() + startZ) + " " + (chunk.getPos().getMinBlockZ() + endZ)); - System.out.println(light); - } - return (byte) light; + //lightBlock = MinecraftWrapper.INSTANCE.getPlayer().level.getLightEngine().getLayerListener(LightType.BLOCK).getLightValue(blockPos); + //lightBlock = MinecraftWrapper.INSTANCE.getPlayer().level.getLightEngine().blockEngine.getLightValue(blockPos); + lightBlock = (byte) blockState.getLightBlock(chunk, blockPos); + return lightBlock; } /** diff --git a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java index 1c6008dae..2a6385a41 100644 --- a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java +++ b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java @@ -46,11 +46,6 @@ import com.seibel.lod.util.LodUtil; */ public class LodDimensionFileHandler { - /** - * This is what separates each piece of data - */ - public static final char DATA_DELIMITER = ','; - private LodDimension loadedDimension = null; public long regionLastWriteTime[][]; @@ -84,7 +79,7 @@ public class LodDimensionFileHandler * 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 = 5; + public static final int LOD_SAVE_FILE_VERSION = 6; /** * This is the string written before the file version diff --git a/src/main/java/com/seibel/lod/objects/LevelContainer.java b/src/main/java/com/seibel/lod/objects/LevelContainer.java index 1e2607ab8..72006de7f 100644 --- a/src/main/java/com/seibel/lod/objects/LevelContainer.java +++ b/src/main/java/com/seibel/lod/objects/LevelContainer.java @@ -9,7 +9,7 @@ import java.util.concurrent.ConcurrentMap; public interface LevelContainer { public static final char VERTICAL_DATA_DELIMITER = '\t'; - public static final char DATA_DELIMITER = ','; + public static final char DATA_DELIMITER = '\n'; /**With this you can add data to the level container * * @param data actual data to add in a array of long format.