diff --git a/src/main/java/com/seibel/lod/builders/LodBuilder.java b/src/main/java/com/seibel/lod/builders/LodBuilder.java index bda1fc230..4c9612703 100644 --- a/src/main/java/com/seibel/lod/builders/LodBuilder.java +++ b/src/main/java/com/seibel/lod/builders/LodBuilder.java @@ -10,6 +10,7 @@ import com.seibel.lod.objects.LodChunk; import com.seibel.lod.objects.LodDataPoint; import com.seibel.lod.objects.LodDimension; import com.seibel.lod.objects.LodWorld; +import com.seibel.lod.util.LodConfig; import com.seibel.lod.util.LodUtils; import net.minecraft.block.BlockState; @@ -28,7 +29,7 @@ import net.minecraft.world.gen.Heightmap; * (specifically: Lod World, Dimension, Region, and Chunk objects) * * @author James Seibel - * @version 6-12-2021 + * @version 6-13-2021 */ public class LodBuilder { @@ -119,11 +120,10 @@ public class LodBuilder public LodChunk generateLodFromChunk(IChunk chunk) throws IllegalArgumentException { if(chunk == null) - { throw new IllegalArgumentException("generateLodFromChunk given a null chunk"); - } - LodDetail detail = LodChunk.DETAIL; + + LodDetail detail = LodConfig.CLIENT.lodDetail.get(); LodDataPoint[][] dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount]; for(int i = 0; i < detail.lengthCount * detail.lengthCount; i++) @@ -134,35 +134,15 @@ public class LodBuilder int endZ = detail.endZ[i]; - Color[] colors = new Color[ColorDirection.values().length]; + Color color = generateLodColorForAreaInDirection(chunk, ColorDirection.TOP, startX, startZ, endX, endZ); - short height = determineTopPointForArea(chunk.getSections(), startX, startZ, endX, endZ); + short height = determineHeightPointForArea(chunk.getSections(), startX, startZ, endX, endZ); short depth = determineBottomPointForArea(chunk.getSections(), startX, startZ, endX, endZ); - - // determine the average color for each direction - for(ColorDirection dir : ColorDirection.values()) - { - colors[dir.value] = generateLodColorForAreaInDirection(chunk, dir, startX, startZ, endX, endZ); - } - - // check to see if there are any invisible sides - for(ColorDirection dir : ColorDirection.values()) - { - // if there are any invisible sides - // replace them with the top side - // (this is done to make sure oceans and other totally - // flat locations have the correct side colors) - if (dir == ColorDirection.BOTTOM || dir == ColorDirection.TOP) - continue; - if (colors[dir.value] == INVISIBLE) - colors[dir.value] = colors[ColorDirection.TOP.value]; - } - int x = i / detail.lengthCount; int z = i % detail.lengthCount; - dataPoints[x][z] = new LodDataPoint(height, depth, colors); + dataPoints[x][z] = new LodDataPoint(height, depth, color); } return new LodChunk(chunk.getPos(), dataPoints); @@ -245,7 +225,7 @@ public class LodBuilder * @param endX * @param endZ */ - private short determineTopPointForArea(ChunkSection[] chunkSections, + private short determineHeightPointForArea(ChunkSection[] chunkSections, int startX, int startZ, int endX, int endZ) { int numberOfBlocksRequired = ((endX-startX) * (endZ-startZ) / 2); @@ -287,7 +267,7 @@ public class LodBuilder * Find the highest point from the Top */ @SuppressWarnings("unused") - private short determineTopPoint(Heightmap heightmap, int endZ) + private short determineHeightPoint(Heightmap heightmap, int endZ) { short highest = 0; for(int x = 0; x < LodChunk.WIDTH; x++) @@ -305,6 +285,8 @@ public class LodBuilder /** * Generate the color for the given chunk in the given ColorDirection. + * NOTE: only vertical is currently implemented for area, + * the horizontal colors will always be the same regardless of the area. */ private Color generateLodColorForAreaInDirection(IChunk chunk, ColorDirection colorDir, int startX, int startZ, int endX, int endZ) { @@ -318,16 +300,15 @@ public class LodBuilder case BOTTOM: return generateLodColorVerticalOverArea(chunk, colorDir, bc, startX, startZ, endX, endZ); - // TODO case NORTH: - return generateLodColorHorizontalOverArea(chunk, colorDir, bc); + return generateLodColorHorizontal(chunk, colorDir, bc); case SOUTH: - return generateLodColorHorizontalOverArea(chunk, colorDir, bc); + return generateLodColorHorizontal(chunk, colorDir, bc); case EAST: - return generateLodColorHorizontalOverArea(chunk, colorDir, bc); + return generateLodColorHorizontal(chunk, colorDir, bc); case WEST: - return generateLodColorHorizontalOverArea(chunk, colorDir, bc); + return generateLodColorHorizontal(chunk, colorDir, bc); } return INVISIBLE; @@ -486,7 +467,7 @@ public class LodBuilder /** * Generates the color for the sides of the given chunk. */ - private Color generateLodColorHorizontalOverArea( + private Color generateLodColorHorizontal( IChunk chunk, ColorDirection colorDir, BlockColors bc) { if(colorDir != ColorDirection.NORTH && colorDir != ColorDirection.SOUTH && colorDir != ColorDirection.EAST && colorDir != ColorDirection.WEST) 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 dbd56cd00..832f1ed77 100644 --- a/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java +++ b/src/main/java/com/seibel/lod/builders/lodTemplates/CubicLodTemplate.java @@ -6,6 +6,7 @@ import com.seibel.lod.enums.ColorDirection; import com.seibel.lod.enums.LodDetail; import com.seibel.lod.objects.LodChunk; import com.seibel.lod.objects.LodDimension; +import com.seibel.lod.util.LodConfig; import net.minecraft.client.renderer.BufferBuilder; import net.minecraft.util.math.AxisAlignedBB; @@ -14,7 +15,7 @@ import net.minecraft.util.math.AxisAlignedBB; * Builds LODs as rectangular prisms. * * @author James Seibel - * @version 06-12-2021 + * @version 06-13-2021 */ public class CubicLodTemplate extends AbstractLodTemplate { @@ -35,7 +36,7 @@ public class CubicLodTemplate extends AbstractLodTemplate // Add this LOD to the BufferBuilder // using the quality setting set by the config - LodDetail detail = LodChunk.DETAIL; //LodConfig.CLIENT.lodDetail.get(); + LodDetail detail = LodConfig.CLIENT.lodDetail.get(); int halfWidth = detail.width / 2; @@ -62,26 +63,7 @@ public class CubicLodTemplate extends AbstractLodTemplate } } - /* - private int[][] addColorToColorAverages(int[][] colorAverages, Color[] colorToAdd) - { - for(ColorDirection dir : ColorDirection.values()) - { - // convert the colorToAdd to an int array - float[] colorCompoments = new float[4]; - colorCompoments = colorToAdd[dir.value].getColorComponents(colorCompoments); - - // add each color component to the array - for(int rgbIndex = 0; rgbIndex < 3; rgbIndex++) - { - // * 255 + 0.5 taken from the Color java class - colorAverages[dir.value][rgbIndex] += (int) (colorCompoments[rgbIndex] * 255 + 0.5); - } - } - - return colorAverages; - } - */ + @@ -103,6 +85,45 @@ public class CubicLodTemplate extends AbstractLodTemplate + private void addBoundingBoxToBuffer(BufferBuilder buffer, AxisAlignedBB bb, Color c) + { + // top (facing up) + addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + // bottom (facing down) + addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + + // south (facing -Z) + addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + // north (facing +Z) + addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + + // west (facing -X) + addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + // east (facing +X) + addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha()); + } + + + + @SuppressWarnings("unused") private void addBoundingBoxToBuffer(BufferBuilder buffer, AxisAlignedBB bb, Color[] c) { // top (facing up) diff --git a/src/main/java/com/seibel/lod/enums/LodColorStyle.java b/src/main/java/com/seibel/lod/enums/LodColorStyle.java deleted file mode 100644 index 4cf829722..000000000 --- a/src/main/java/com/seibel/lod/enums/LodColorStyle.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.seibel.lod.enums; - -/** - * top, individual_sides - * - * @author James Seibel - * @version 05-08-2021 - */ -public enum LodColorStyle -{ - /** Use the color from the top of the LOD chunk - * for all sides */ - TOP, - - /** For each side of the LOD use the color corresponding - * to that side */ - INDIVIDUAL_SIDES; -} diff --git a/src/main/java/com/seibel/lod/enums/LodDetail.java b/src/main/java/com/seibel/lod/enums/LodDetail.java index af4c40e93..f4dd38eee 100644 --- a/src/main/java/com/seibel/lod/enums/LodDetail.java +++ b/src/main/java/com/seibel/lod/enums/LodDetail.java @@ -1,12 +1,13 @@ package com.seibel.lod.enums; import com.seibel.lod.objects.LodChunk; +import com.seibel.lod.objects.LodDataPoint; /** * single, double, quad, half, full * * @author James Seibel - * @version 06-12-2021 + * @version 06-13-2021 */ public enum LodDetail { @@ -32,13 +33,20 @@ public enum LodDetail /** How wide each LOD is */ public final int width; - /* */ + /* Start/End X/Z give the block positions + * for each individual dataPoint in a LodChunk */ public final int[] startX; public final int[] startZ; public final int[] endX; public final int[] endZ; + /** This is how many pieces of data should be expected + * when creating a LodChunk with this detail level */ + public final int lodChunkStringDelimiterCount; + + + private LodDetail(int newLengthCount) { @@ -81,5 +89,9 @@ public enum LodDetail index++; } } - } + + + lodChunkStringDelimiterCount = 2 + (lengthCount * lengthCount * LodDataPoint.NUMBER_OF_DELIMITERS); + + }// constructor } diff --git a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java index cd528e5b4..5b75f8260 100644 --- a/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java +++ b/src/main/java/com/seibel/lod/handlers/LodDimensionFileHandler.java @@ -8,10 +8,12 @@ import java.io.IOException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import com.seibel.lod.enums.LodDetail; import com.seibel.lod.objects.LodChunk; import com.seibel.lod.objects.LodDimension; import com.seibel.lod.objects.LodRegion; import com.seibel.lod.proxy.ClientProxy; +import com.seibel.lod.util.LodConfig; /** * This object handles creating LodRegions @@ -19,7 +21,7 @@ import com.seibel.lod.proxy.ClientProxy; * to file. * * @author James Seibel - * @version 6-12-2021 + * @version 6-13-2021 */ public class LodDimensionFileHandler { @@ -32,13 +34,16 @@ public class LodDimensionFileHandler private File dimensionDataSaveFolder; + /** lod */ private final String FILE_NAME_PREFIX = "lod"; + /** .txt */ private final String FILE_EXTENSION = ".txt"; /** 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 = 1; + public static final int LOD_SAVE_FILE_VERSION = 2; + /** This is the string written before the file version */ private static final String LOD_FILE_VERSION_PREFIX = "lod_save_file_version"; @@ -78,10 +83,8 @@ public class LodDimensionFileHandler */ public LodRegion loadRegionFromFile(int regionX, int regionZ) { - // TODO - return null; - /* - String fileName = getFileNameAndPathForRegion(regionX, regionZ); + + String fileName = getFileNameAndPathForRegion(regionX, regionZ, LodConfig.CLIENT.lodDetail.get()); File f = new File(fileName); @@ -156,7 +159,7 @@ public class LodDimensionFileHandler try { // convert each line into an LOD object and add it to the region - LodChunk lod = new LodChunk(s); + LodChunk lod = new LodChunk(s, LodConfig.CLIENT.lodDetail.get()); region.addLod(lod); } @@ -181,7 +184,6 @@ public class LodDimensionFileHandler } return region; - */ } @@ -200,8 +202,7 @@ public class LodDimensionFileHandler */ public void saveDirtyRegionsToFileAsync() { - // TODO - //fileWritingThreadPool.execute(saveDirtyRegionsThread); + fileWritingThreadPool.execute(saveDirtyRegionsThread); } private Thread saveDirtyRegionsThread = new Thread(() -> @@ -234,7 +235,7 @@ public class LodDimensionFileHandler int x = region.x; int z = region.z; - File f = new File(getFileNameAndPathForRegion(x, z)); + File f = new File(getFileNameAndPathForRegion(x, z, LodConfig.CLIENT.lodDetail.get())); try { @@ -320,9 +321,11 @@ public class LodDimensionFileHandler /** * 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 this object isn't ready to read and write.

+ * + * example: "lod.FULL.0.0.txt" */ - private String getFileNameAndPathForRegion(int regionX, int regionZ) + private String getFileNameAndPathForRegion(int regionX, int regionZ, LodDetail detail) { try { @@ -330,8 +333,8 @@ public class LodDimensionFileHandler // ".\Super Flat\DIM-1\data" // or // ".\Super Flat\data" - return dimensionDataSaveFolder.getCanonicalPath() + "\\" + - FILE_NAME_PREFIX + "." + regionX + "." + regionZ + FILE_EXTENSION; + return dimensionDataSaveFolder.getCanonicalPath() + "\\" + + FILE_NAME_PREFIX + "." + detail.toString() + "." + regionX + "." + regionZ + FILE_EXTENSION; } catch(IOException e) { diff --git a/src/main/java/com/seibel/lod/objects/LodChunk.java b/src/main/java/com/seibel/lod/objects/LodChunk.java index e4bb7d18b..e2213e0b0 100644 --- a/src/main/java/com/seibel/lod/objects/LodChunk.java +++ b/src/main/java/com/seibel/lod/objects/LodChunk.java @@ -2,10 +2,8 @@ package com.seibel.lod.objects; import java.awt.Color; -import com.seibel.lod.enums.ColorDirection; import com.seibel.lod.enums.LodDetail; import com.seibel.lod.handlers.LodDimensionFileHandler; -import com.seibel.lod.util.LodConfig; import net.minecraft.util.math.ChunkPos; @@ -14,13 +12,10 @@ import net.minecraft.util.math.ChunkPos; * and color data for an LOD object. * * @author James Seibel - * @version 6-12-2021 + * @version 6-13-2021 */ public class LodChunk { - /** how many different pieces of data are in one line */ - private static final int DATA_DELIMITER_COUNT = 22; - /** This is what separates each piece of data in the toData method */ private static final char DATA_DELIMITER = LodDimensionFileHandler.DATA_DELIMITER; @@ -34,7 +29,7 @@ public class LodChunk private static final Color INVISIBLE = new Color(0,0,0,0); - public static final LodDetail DETAIL = LodDetail.QUAD; + public LodDetail detail = LodDetail.SINGLE; /** The x coordinate of the chunk. */ @@ -60,11 +55,12 @@ public class LodChunk x = 0; z = 0; - dataPoints = new LodDataPoint[DETAIL.lengthCount][DETAIL.lengthCount]; + detail = LodDetail.SINGLE; + + dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount]; } - // TODO /** * Creates an LodChunk from the string * generated by the toData method. @@ -72,97 +68,99 @@ public class LodChunk * @throws IllegalArgumentException if the data isn't valid to create a LodChunk * @throws NumberFormatException if any piece of data can't be converted at any point */ -// public LodChunk(String data) throws IllegalArgumentException, NumberFormatException -// { -// /* -// * data format: -// * x, z, height, depth, rgb color data -// * -// * example: -// * 5,8, 4, 0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, -// */ -// -// // make sure there are the correct number of entries -// // in the data string (28) -// int count = 0; -// -// for(int i = 0; i < data.length(); i++) -// if(data.charAt(i) == DATA_DELIMITER) -// count++; -// -// if(count != DATA_DELIMITER_COUNT) -// throw new IllegalArgumentException("LodChunk constructor givin an invalid string. The data given had " + count + " delimiters when it should have had " + DATA_DELIMITER_COUNT + "."); -// -// -// -// // index we will use when going through the String -// int index = 0; -// int lastIndex = 0; -// -// -// -// // x and z position -// index = data.indexOf(DATA_DELIMITER, 0); -// x = Integer.parseInt(data.substring(0,index)); -// -// lastIndex = index; -// index = data.indexOf(DATA_DELIMITER, lastIndex+1); -// z = Integer.parseInt(data.substring(lastIndex+1,index)); -// -// // height -// lastIndex = index; -// index = data.indexOf(DATA_DELIMITER, lastIndex+1); -// // TODO -// //height = Short.parseShort(data.substring(lastIndex+1,index)); -// -// // depth -// lastIndex = index; -// index = data.indexOf(DATA_DELIMITER, lastIndex+1); -// //depth = Short.parseShort(data.substring(lastIndex+1,index)); -// -// -// -// // color -// //colors = new Color[6]; -// for(ColorDirection dir : ColorDirection.values()) -// { -// int red = 0; -// int green = 0; -// int blue = 0; -// -// // get r,g,b -// for(int i = 0; i < 3; i++) -// { -// lastIndex = index; -// index = data.indexOf(DATA_DELIMITER, lastIndex + 1); -// -// String raw = ""; -// switch(i) -// { -// case 0: -// raw = data.substring(lastIndex+1,index); -// red = Short.parseShort(raw); -// break; -// case 1: -// raw = data.substring(lastIndex+1,index); -// green = Short.parseShort(raw); -// break; -// case 2: -// raw = data.substring(lastIndex+1,index); -// blue = Short.parseShort(raw); -// break; -// } -// } -// -// // TODO -// //colors[dir.value] = new Color(red, green, blue); -// } -// -// -// // after going through all this -// // is this LOD empty? -// empty = determineIfEmtpy(); -// } + public LodChunk(String data, LodDetail newDetail) throws IllegalArgumentException, NumberFormatException + { + /* + * data format: + * x, z, dataPoint[0][0], dataPoint[0][1], ... + * x, z, height, depth, rgb color data, height, depth, rgb.... + * + * example: + * 5,8, 4, 0, 255,255,255, 4, 0, 255, 255, 255, ... + */ + + // make sure there are the correct number of entries + // in the data string + int count = 0; + + for(int i = 0; i < data.length(); i++) + if(data.charAt(i) == DATA_DELIMITER) + count++; + + if(count != detail.lodChunkStringDelimiterCount) + throw new IllegalArgumentException("LodChunk constructor givin an invalid string. The data given had " + count + " delimiters when it should have had " + detail.lodChunkStringDelimiterCount + "."); + + + detail = newDetail; + dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount]; + + // index we will use when going through the String + int index = 0; + int lastIndex = 0; + + + + // x and z position + index = data.indexOf(DATA_DELIMITER, 0); + this.x = Integer.parseInt(data.substring(0,index)); + + lastIndex = index; + index = data.indexOf(DATA_DELIMITER, lastIndex+1); + this.z = Integer.parseInt(data.substring(lastIndex+1,index)); + + + // LodDataPoints + for(int blockX = 0; blockX < detail.lengthCount; blockX++) + { + for(int blockZ = 0; blockZ < detail.lengthCount; blockZ++) + { + // height + lastIndex = index; + index = data.indexOf(DATA_DELIMITER, lastIndex+1); + int height = Short.parseShort(data.substring(lastIndex+1,index)); + + // depth + lastIndex = index; + index = data.indexOf(DATA_DELIMITER, lastIndex+1); + int depth = Short.parseShort(data.substring(lastIndex+1,index)); + + + // color + int red = 0; + int green = 0; + int blue = 0; + + // get r,g,b + for(int i = 0; i < 3; i++) + { + lastIndex = index; + index = data.indexOf(DATA_DELIMITER, lastIndex + 1); + + String raw = ""; + switch(i) + { + case 0: + raw = data.substring(lastIndex+1,index); + red = Short.parseShort(raw); + break; + case 1: + raw = data.substring(lastIndex+1,index); + green = Short.parseShort(raw); + break; + case 2: + raw = data.substring(lastIndex+1,index); + blue = Short.parseShort(raw); + break; + } + } + + dataPoints[blockX][blockZ] = new LodDataPoint((short)height, (short)depth, new Color(red, green, blue)); + } + } + + + empty = determineIfEmtpy(); + } /** * Create a LodChunk from the given values. @@ -218,11 +216,13 @@ public class LodChunk if(dataPoint.height >= 0) { // the height is valid, - // do we have at least 1 non-invisible color? - for(ColorDirection dir : ColorDirection.values()) - if(!dataPoint.colors[dir.value].equals(INVISIBLE)) - // at least one direction has a non-invisible color - return false; + + if (dataPoint.color == INVISIBLE) + continue; + + // the color and height are valid + // this LodChunk isn't empty + return false; } } } @@ -243,16 +243,12 @@ public class LodChunk */ public LodDataPoint getDataPointForBlockPos(int blockX, int blockZ) { - if (blockX < 0 || blockX > WIDTH || blockX < 0 || blockZ > WIDTH) - throw new IllegalArgumentException("The coordinates given are outside the LodChunk"); - - return dataPoints[blockX / DETAIL.width][blockZ / DETAIL.width]; + return dataPoints[blockX / detail.width][blockZ / detail.width]; } - /** Returns the color for the given direction */ - public Color getColorForBlockPos(int blockX, int blockZ, ColorDirection dir) + public Color getColorForBlockPos(int blockX, int blockZ) { - return getDataPointForBlockPos(blockX, blockZ).colors[dir.value]; + return getDataPointForBlockPos(blockX, blockZ).color; } public short getHeightForBlockPos(int blockX, int blockZ) @@ -266,6 +262,23 @@ public class LodChunk } + public Color getColor(int xIndex, int zIndex) + { + return dataPoints[xIndex][zIndex].color; + } + + public short getHeight(int xIndex, int zIndex) + { + return dataPoints[xIndex][zIndex].height; + } + + public short getDepth(int xIndex, int zIndex) + { + return dataPoints[xIndex][zIndex].depth; + } + + + /** * @param startX * @param startZ @@ -304,68 +317,71 @@ public class LodChunk /** - * Determine the color for each side of this LOD. + * Determine the color of this LOD. */ - public Color[] getAverageColorOverArea(int startX, int startZ, int endX, int endZ, boolean debugging) + public Color getAverageColorOverArea(int startX, int startZ, int endX, int endZ, boolean debugging) { - Color[] colors = new Color[ColorDirection.values().length]; + int[] colorComponents = new int[3]; + + + if (debugging) + { + // draw the squares as a black and white, + // like a checker board + + // only return 1 color to prevent + // getting back gray + if ((startX + startZ) % 2 == 0) + return DEBUG_WHITE; + else + return DEBUG_BLACK; + } + for(int x = startX; x < endX; x++) { for(int z = startZ; z < endZ; z++) { - if (!debugging) - { - // if NOT debugging, look to the config to determine - // how this LOD should be colored - switch (LodConfig.CLIENT.lodColorStyle.get()) - { - case TOP: - // only add the top's color to the array - for(ColorDirection dir : ColorDirection.values()) - colors[dir.value] = getColorForBlockPos(x,z, ColorDirection.TOP); - break; - - case INDIVIDUAL_SIDES: - // add each direction's color to the array - for(ColorDirection dir : ColorDirection.values()) - colors[dir.value] = getColorForBlockPos(x,z, dir); - break; - } - } - else - { - // if debugging draw the squares as a black and white checker board - if ((x + z) % 2 == 0) - for(ColorDirection dir : ColorDirection.values()) - // have each direction be the same - // color if debugging - colors[dir.value] = DEBUG_WHITE; - else - for(ColorDirection dir : ColorDirection.values()) - colors[dir.value] = DEBUG_BLACK; - } + colorComponents = addColorToColorAverages(colorComponents, getColorForBlockPos(x,z)); } } - return colors; + int numbPoints = ((endX - startX) * (endZ - startZ)); + + return new Color(colorComponents[0]/numbPoints, colorComponents[1]/numbPoints, colorComponents[2]/numbPoints); } + private int[] addColorToColorAverages(int[] colorAverages, Color colorToAdd) + { + // convert the colorToAdd to an int array + float[] colorCompoments = new float[4]; + colorCompoments = colorToAdd.getColorComponents(colorCompoments); + + // add each color component to the array + for(int rgbIndex = 0; rgbIndex < 3; rgbIndex++) + { + // * 255 + 0.5 taken from the Color java class + colorAverages[rgbIndex] += (int) (colorCompoments[rgbIndex] * 255 + 0.5); + } + + return colorAverages; + } + + + /** * Outputs all data in a csv format - * with the given delimiter. - *
- * Exports data in the form: - *
- * x, z, height, depth, rgb color data + * with the given delimiter.

* - *
- * example output: - *
- * 5,8, 4, 0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, + * data format:
+ * x, z, dataPoint[0][0], dataPoint[0][1], ...
+ * x, z, height, depth, rgb color data, height, depth, rgb....

+ * + * example:
+ * 5,8, 4, 0, 255,255,255, 4, 0, 255, 255, 255, ... */ public String toData() { @@ -373,9 +389,9 @@ public class LodChunk s += Integer.toString(x) + DATA_DELIMITER + Integer.toString(z) + DATA_DELIMITER; - for (LodDataPoint[] dataPointArray : dataPoints) - for(LodDataPoint dataPoint : dataPointArray) - s += dataPoint.toData(); + for (int i = 0; i < dataPoints.length; i++) + for (int j = 0; j < dataPoints[i].length; j++) + s += dataPoints[i][j].toData(); return s; } @@ -388,9 +404,6 @@ public class LodChunk s += "x: " + x + " z: " + z + "\t"; - // TODO - //s += "(" + colors[ColorDirection.TOP.value].getRed() + ", " + colors[ColorDirection.TOP.value].getGreen() + ", " + colors[ColorDirection.TOP.value].getBlue() + ")"; - return s; } } diff --git a/src/main/java/com/seibel/lod/objects/LodDataPoint.java b/src/main/java/com/seibel/lod/objects/LodDataPoint.java index 2917c8f67..117b5f425 100644 --- a/src/main/java/com/seibel/lod/objects/LodDataPoint.java +++ b/src/main/java/com/seibel/lod/objects/LodDataPoint.java @@ -2,7 +2,6 @@ package com.seibel.lod.objects; import java.awt.Color; -import com.seibel.lod.enums.ColorDirection; import com.seibel.lod.handlers.LodDimensionFileHandler; /** @@ -10,13 +9,16 @@ import com.seibel.lod.handlers.LodDimensionFileHandler; * for a specific area in a LodChunk. * * @author James Seibel - * @version 6-12-2021 + * @version 6-13-2021 */ public class LodDataPoint { /** This is what separates each piece of data in the toData method */ private static final char DATA_DELIMITER = LodDimensionFileHandler.DATA_DELIMITER; + /** this is how many pieces of data are exported when toData is called */ + public static final int NUMBER_OF_DELIMITERS = 5; + private static final Color INVISIBLE = new Color(0,0,0,0); /** highest point */ @@ -26,29 +28,25 @@ public class LodDataPoint public short depth; /** The average color for the 6 cardinal directions */ - public Color colors[]; + public Color color; /** - * default constructor + * Creates and empty LodDataPoint */ public LodDataPoint() { - height = 0; - depth = 0; - colors = new Color[ColorDirection.values().length]; - - // by default have the colors invisible - for(ColorDirection dir : ColorDirection.values()) - colors[dir.value] = INVISIBLE; + height = -1; + depth = -1; + color = INVISIBLE; } - public LodDataPoint(short newHeight, short newDepth, Color[] newColors) + public LodDataPoint(short newHeight, short newDepth, Color newColor) { height = newHeight; depth = newDepth; - colors = newColors; + color = newColor; } @@ -63,19 +61,15 @@ public class LodDataPoint *
* example output: *
- * 4, 0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, + * 4, 0, 255,255,255, */ public String toData() { - String s = Short.toString(height) + DATA_DELIMITER; s += Short.toString(depth) + DATA_DELIMITER; - for(int i = 0; i < colors.length; i++) - { - s += Integer.toString(colors[i].getRed()) + DATA_DELIMITER + Integer.toString(colors[i].getGreen()) + DATA_DELIMITER + Integer.toString(colors[i].getBlue()) + DATA_DELIMITER; - } + s += Integer.toString(color.getRed()) + DATA_DELIMITER + Integer.toString(color.getGreen()) + DATA_DELIMITER + Integer.toString(color.getBlue()) + DATA_DELIMITER; return s; } diff --git a/src/main/java/com/seibel/lod/util/LodConfig.java b/src/main/java/com/seibel/lod/util/LodConfig.java index d6b50bd5c..443122b9d 100644 --- a/src/main/java/com/seibel/lod/util/LodConfig.java +++ b/src/main/java/com/seibel/lod/util/LodConfig.java @@ -10,7 +10,6 @@ import com.electronwill.nightconfig.core.file.CommentedFileConfig; import com.electronwill.nightconfig.core.io.WritingMode; import com.seibel.lod.ModInfo; import com.seibel.lod.enums.FogDistance; -import com.seibel.lod.enums.LodColorStyle; import com.seibel.lod.enums.LodDetail; import com.seibel.lod.enums.LodTemplate; @@ -22,7 +21,7 @@ import net.minecraftforge.fml.config.ModConfig; /** * * @author James Seibel - * @version 05-31-2021 + * @version 6-13-2021 */ @Mod.EventBusSubscriber public class LodConfig @@ -39,8 +38,6 @@ public class LodConfig public ForgeConfigSpec.EnumValue lodDetail; - public ForgeConfigSpec.EnumValue lodColorStyle; - /** this is multiplied by the default view distance * to determine how far out to generate/render LODs */ public ForgeConfigSpec.IntValue lodChunkRadiusMultiplier; @@ -87,13 +84,6 @@ public class LodConfig + " " + LodDetail.DOUBLE.toString() + ": render 4 LODs for each Chunk.") .defineEnum("lodGeometryQuality", LodDetail.SINGLE); - lodColorStyle = builder - .comment("\n" - + " How should the LODs be colored? \n" - + " " + LodColorStyle.TOP.toString() + ": Use the color from the top of the LOD chunk for all sides. \n" - + " " + LodColorStyle.INDIVIDUAL_SIDES.toString() + ": For each side of the LOD use the color corresponding to that side. ") - .defineEnum("lodColorStyle", LodColorStyle.TOP); - lodChunkRadiusMultiplier = builder .comment("\n" + " This is multiplied by the default view distance \n"