From 811e24ee5e2cecf22be8293680cf2b5094046d2a Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 29 May 2021 13:00:43 -0500 Subject: [PATCH] Improve and simplify LodChunk --- .../com/backsun/lod/builders/LodBuilder.java | 255 ++++++------------ .../lodTemplates/CubicLodTemplate.java | 163 ++++++----- .../com/backsun/lod/objects/LodChunk.java | 166 ++++++------ 3 files changed, 243 insertions(+), 341 deletions(-) diff --git a/src/main/java/com/backsun/lod/builders/LodBuilder.java b/src/main/java/com/backsun/lod/builders/LodBuilder.java index cc50ed8aa..3d4129f59 100644 --- a/src/main/java/com/backsun/lod/builders/LodBuilder.java +++ b/src/main/java/com/backsun/lod/builders/LodBuilder.java @@ -5,7 +5,6 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import com.backsun.lod.enums.ColorDirection; -import com.backsun.lod.enums.LodLocation; import com.backsun.lod.objects.LodChunk; import com.backsun.lod.objects.LodDimension; import com.backsun.lod.objects.LodWorld; @@ -26,7 +25,7 @@ import net.minecraft.world.gen.Heightmap; * (specifically: Lod World, Dimension, Region, and Chunk objects) * * @author James Seibel - * @version 4-01-2021 + * @version 5-29-2021 */ public class LodBuilder { @@ -37,16 +36,15 @@ public class LodBuilder public static final int CHUNK_DATA_WIDTH = LodChunk.WIDTH; - public static final int CHUNK_DATA_HEIGHT = LodChunk.WIDTH; + public static final int CHUNK_SECTION_HEIGHT = LodChunk.WIDTH; /** * This is how many blocks are * required at a specific y-value * to constitute a LOD point */ - private final int LOD_BLOCK_REQ = 16; + private final int LOD_BLOCK_REQ = 32; // the max number of blocks per layer = 64 (8*8) - // since each layer is 1/4 the chunk public LodBuilder() @@ -115,8 +113,7 @@ public class LodBuilder /** - * Creates a LodChunk for a chunk in the given world.
- * Note: The world is required to determine each block's color + * Creates a LodChunk for a chunk in the given world. * * @throws IllegalArgumentException * thrown if either the chunk or world is null. @@ -128,16 +125,12 @@ public class LodBuilder throw new IllegalArgumentException("generateLodFromChunk given a null chunk"); } - short[] top = new short[4]; - short[] bottom = new short[4]; - Color[] colors = new Color[6]; + Color[] colors = new Color[ColorDirection.values().length]; + + + short height = determineTopPoint(chunk.getSections()); + short depth = determineBottomPoint(chunk.getSections()); - // generate the top and bottom points of this LOD - for(LodLocation loc : LodLocation.values()) - { - top[loc.value] = generateLodCorner(chunk, SectionGenerationMode.GENERATE_TOP, loc); - bottom[loc.value] = generateLodCorner(chunk, SectionGenerationMode.GENERATE_BOTTOM, loc); - } // determine the average color for each direction for(ColorDirection dir : ColorDirection.values()) @@ -145,7 +138,7 @@ public class LodBuilder colors[dir.value] = generateLodColorForDirection(chunk, dir); } - return new LodChunk(chunk.getPos(), top, bottom, colors); + return new LodChunk(chunk.getPos(), height, depth, colors); } @@ -157,100 +150,24 @@ public class LodBuilder // constructor helpers // //=====================// - /** GENERATE_TOP, GENERATE_BOTTOM */ - private enum SectionGenerationMode - { - GENERATE_TOP, - GENERATE_BOTTOM; - } - - /** - * Generate the height for the given LodLocation, either the top or bottom. - *

- * If invalid/null/empty chunks are given - * crashes may occur. - */ - public short generateLodCorner(IChunk chunk, SectionGenerationMode sectionGenMode, LodLocation lodLoc) - { - int startX = 0; - int endX = 0; - - int startZ = 0; - int endZ = 0; - - // determine where we should look in this - // chunk - switch(lodLoc) - { - case NE: - // -N - startZ = 0; - endZ = (CHUNK_DATA_WIDTH / 2) - 1; - // +E - startX = CHUNK_DATA_WIDTH / 2; - endX = CHUNK_DATA_WIDTH - 1; - break; - - case SE: - // +S - startZ = CHUNK_DATA_WIDTH / 2; - endZ = CHUNK_DATA_WIDTH; - // +E - startX = CHUNK_DATA_WIDTH / 2; - endX = CHUNK_DATA_WIDTH; - break; - - case SW: - // +S - startZ = CHUNK_DATA_WIDTH / 2; - endZ = CHUNK_DATA_WIDTH; - // -W - startX = 0; - endX = (CHUNK_DATA_WIDTH / 2) - 1; - break; - - case NW: - // -N - startZ = 0; - endZ = CHUNK_DATA_WIDTH / 2; - // -W - startX = 0; - endX = CHUNK_DATA_WIDTH / 2; - break; - } - - - // should have a length of 16 - // (each storage is 16x16x16 and the - // world height is 256) - ChunkSection[] chunkSections = chunk.getSections(); - - - if(sectionGenMode == SectionGenerationMode.GENERATE_TOP) - return determineTopPoint(chunkSections, startX, endX, startZ, endZ); - else - return determineBottomPoint(chunkSections, startX, endX, startZ, endZ); - } - /** * Find the lowest valid point from the bottom. */ - private short determineBottomPoint(ChunkSection[] chunkSections, int startX, int endX, int startZ, int endZ) + private short determineBottomPoint(ChunkSection[] chunkSections) { // search from the bottom up for(int i = 0; i < CHUNK_DATA_WIDTH; i++) { - for(int y = 0; y < CHUNK_DATA_HEIGHT; y++) + for(int y = 0; y < CHUNK_SECTION_HEIGHT; y++) { - - if(isLayerValidLodPoint(chunkSections, startX, endX, startZ, endZ, i, y)) + if(isLayerValidLodPoint(chunkSections, i, y)) { // we found // enough blocks in this // layer to count as an // LOD point - return (short) (y + (i * CHUNK_DATA_HEIGHT)); + return (short) (y + (i * CHUNK_SECTION_HEIGHT)); } } } @@ -263,7 +180,7 @@ public class LodBuilder * Find the lowest valid point from the bottom. */ @SuppressWarnings("unused") - private short determineBottomPoint(Heightmap heightmap, int startX, int endX, int startZ, int endZ) + 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 @@ -275,20 +192,20 @@ public class LodBuilder /** * Find the highest valid point from the Top */ - private short determineTopPoint(ChunkSection[] chunkSections, int startX, int endX, int startZ, int endZ) + private short determineTopPoint(ChunkSection[] chunkSections) { // search from the top down - for(int i = chunkSections.length - 1; i >= 0; i--) + for(int section = chunkSections.length - 1; section >= 0; section--) { for(int y = CHUNK_DATA_WIDTH - 1; y >= 0; y--) { - if(isLayerValidLodPoint(chunkSections, startX, endX, startZ, endZ, i, y)) + if(isLayerValidLodPoint(chunkSections, section, y)) { // we found // enough blocks in this // layer to count as an // LOD point - return (short) (y + (i * CHUNK_DATA_HEIGHT)); + return (short) (y + (section * CHUNK_SECTION_HEIGHT)); } } } @@ -298,15 +215,15 @@ public class LodBuilder } /** - * Find the highest valid point from the Top + * Find the highest point from the Top */ @SuppressWarnings("unused") - private short determineTopPoint(Heightmap heightmap, int startX, int endX, int startZ, int endZ) + private short determineTopPoint(Heightmap heightmap, int endZ) { short highest = 0; - for(int x = startX; x < endX; x++) + for(int x = 0; x < LodChunk.WIDTH; x++) { - for(int z = startZ; z < endZ; z++) + for(int z = 0; z < LodChunk.WIDTH; z++) { short newHeight = (short) heightmap.getHeight(x, z); if (newHeight > highest) @@ -329,17 +246,15 @@ public class LodBuilder * values a valid LOD point? */ private boolean isLayerValidLodPoint( - ChunkSection[] chunkSections, - int startX, int endX, - int startZ, int endZ, + ChunkSection[] chunkSections, int sectionIndex, int y) { // search through this layer int layerBlocks = 0; - for(int x = startX; x < endX; x++) + for(int x = 0; x < LodChunk.WIDTH; x++) { - for(int z = startZ; z < endZ; z++) + for(int z = 0; z < LodChunk.WIDTH; z++) { if(chunkSections[sectionIndex] == null) { @@ -349,7 +264,8 @@ public class LodBuilder } else { - if(chunkSections[sectionIndex].getBlockState(x, y, z) != null && chunkSections[sectionIndex].getBlockState(x, y, z).getBlock() != Blocks.AIR) + if(chunkSections[sectionIndex].getBlockState(x, y, z) != null && + chunkSections[sectionIndex].getBlockState(x, y, z).getBlock() != Blocks.AIR) { // we found a valid block in // in this layer @@ -369,37 +285,7 @@ public class LodBuilder } /** - * Generate the color of the given ColorDirection at the given chunk - * in the given world. - */ - private Color generateLodColorForDirection(IChunk chunk, ColorDirection colorDir) - { - Minecraft mc = Minecraft.getInstance(); - BlockColors bc = mc.getBlockColors(); - - switch (colorDir) - { - case TOP: - return generateLodColorVertical(chunk, colorDir, bc); - case BOTTOM: - return generateLodColorVertical(chunk, colorDir, bc); - - case NORTH: - return generateLodColorHorizontal(chunk, colorDir, bc); - case SOUTH: - return generateLodColorHorizontal(chunk, colorDir, bc); - - case EAST: - return generateLodColorHorizontal(chunk, colorDir, bc); - case WEST: - return generateLodColorHorizontal(chunk, colorDir, bc); - } - - return new Color(0, 0, 0, 0); - } - - /** - * Generates the color of the top or bottom of a given chunk in the given world. + * Generates the color of the top or bottom of the given chunk. * * @throws IllegalArgumentException if given a ColorDirection other than TOP or BOTTOM */ @@ -428,8 +314,8 @@ public class LodBuilder int dataMin = 0; int dataIncrement = goTopDown? -1 : 1; - int topStart = goTopDown? CHUNK_DATA_HEIGHT - 1 : 0; - int topMax = CHUNK_DATA_HEIGHT; + int topStart = goTopDown? CHUNK_SECTION_HEIGHT - 1 : 0; + int topMax = CHUNK_SECTION_HEIGHT; int topMin = 0; int topIncrement = goTopDown? -1 : 1; @@ -481,6 +367,7 @@ public class LodBuilder blue /= numbOfBlocks; return new Color(red, green, blue); + } /* * unused variation that can be used with only the heightmap, @@ -496,29 +383,25 @@ public class LodBuilder for(int x = 0; x < CHUNK_DATA_WIDTH; x++) { - for(int z = 0; z < CHUNK_DATA_WIDTH; z++) - { - Biome biome = chunk.getBiomes().getNoiseBiome(x,z, heightmap.getHeight(x, z)); - Color c = intToColor(biome.getFoliageColor()); - - red += c.getRed(); - green += c.getGreen(); - blue += c.getBlue(); - } + Biome biome = chunk.getBiomes().getNoiseBiome(x,z, heightmap.getHeight(x, z)); + Color c = intToColor(biome.getFoliageColor()); + + red += c.getRed(); + green += c.getGreen(); + blue += c.getBlue(); } - - red /= numbOfBlocks; - green /= numbOfBlocks; - blue /= numbOfBlocks; - - return new Color(red, green, blue); - */ - } + } + + red /= numbOfBlocks; + green /= numbOfBlocks; + blue /= numbOfBlocks; + + return new Color(red, green, blue); + */ + /** - * Generates the color of the side of a given chunk in the given world for the given ColorDirection. - * - * @throws IllegalArgumentException if given a ColorDirection other than N, S, W, E (North, South, East, West) + * Generates the color for the sides of the given chunk. */ private Color generateLodColorHorizontal(IChunk chunk, ColorDirection colorDir, BlockColors bc) { @@ -572,13 +455,14 @@ public class LodBuilder { if (chunkSections[i] != null) { - for (int y = 0; y < CHUNK_DATA_HEIGHT; y++) + for (int y = 0; y < CHUNK_SECTION_HEIGHT; y++) { + // TODO #24 only add colors that are visible, IE don't add stone blocks that are surrounded by other stone blocks + boolean foundBlock = false; // over moves "over" the side of the chunk // in moves "into" the chunk until it finds a block - for (int over = overStart; !foundBlock && over >= 0 && over < CHUNK_DATA_WIDTH; over += overIncrement) { for (int in = inStart; !foundBlock && in >= 0 && in < CHUNK_DATA_WIDTH; in += inIncrement) @@ -648,6 +532,43 @@ public class LodBuilder } + + + + + /** + * Generate the color for the given chunk in the given ColorDirection. + */ + private Color generateLodColorForDirection(IChunk chunk, ColorDirection colorDir) + { + Minecraft mc = Minecraft.getInstance(); + BlockColors bc = mc.getBlockColors(); + + switch (colorDir) + { + case TOP: + return generateLodColorVertical(chunk, colorDir, bc); + case BOTTOM: + return generateLodColorVertical(chunk, colorDir, bc); + + case NORTH: + return generateLodColorHorizontal(chunk, colorDir, bc); + case SOUTH: + return generateLodColorHorizontal(chunk, colorDir, bc); + + case EAST: + return generateLodColorHorizontal(chunk, colorDir, bc); + case WEST: + return generateLodColorHorizontal(chunk, colorDir, bc); + } + + return new Color(0, 0, 0, 0); + } + + + + + /** * Convert a BlockColors int into a Color object. */ diff --git a/src/main/java/com/backsun/lod/builders/lodTemplates/CubicLodTemplate.java b/src/main/java/com/backsun/lod/builders/lodTemplates/CubicLodTemplate.java index 80e9de9e7..b0795b97e 100644 --- a/src/main/java/com/backsun/lod/builders/lodTemplates/CubicLodTemplate.java +++ b/src/main/java/com/backsun/lod/builders/lodTemplates/CubicLodTemplate.java @@ -3,7 +3,7 @@ package com.backsun.lod.builders.lodTemplates; import java.awt.Color; import com.backsun.lod.enums.ColorDirection; -import com.backsun.lod.enums.LodCorner; +import com.backsun.lod.enums.LodDetail; import com.backsun.lod.objects.LodChunk; import com.backsun.lod.objects.LodDimension; import com.backsun.lod.util.LodConfig; @@ -15,7 +15,7 @@ import net.minecraft.util.math.AxisAlignedBB; * Builds each LOD chunk as a singular rectangular prism. * * @author James Seibel - * @version 05-19-2021 + * @version 05-29-2021 */ public class CubicLodTemplate extends AbstractLodTemplate { @@ -33,12 +33,61 @@ public class CubicLodTemplate extends AbstractLodTemplate boolean debugging) { AxisAlignedBB bbox; - int topPoint = getValidHeightPoint(lod.top); - int bottomPoint = getValidHeightPoint(lod.bottom); + + + // Add this LOD to the BufferBuilder + // using the quality setting set by the config + switch(LodConfig.CLIENT.lodDetail.get()) + { + case SINGLE: + // returns null if the lod is empty at the given location + bbox = generateBoundingBox(lod, LodChunk.WIDTH, xOffset, yOffset, zOffset); + + if (bbox != null) + { + addBoundingBoxToBuffer(buffer, bbox, generateLodColors(lod, false)); + } + + break; + + case QUAD: + + // TODO use the adjacent chunks to generate quarter sections +// width = LodChunk.WIDTH / LodDetail.QUAD.value; +// +// for(int i = 0; i < LodDetail.QUAD.value; i++) +// { +// for(int j = 0; j < LodDetail.QUAD.value; j++) +// { +// int x = i * width; +// int z = j * width; +// +// // returns null if the lod is empty at the given location +// bbox = generateBoundingBox(lod, x, z, width, xOffset - (width / 2) + x, yOffset, zOffset - (width / 2) + z); +// +// if (bbox != null) +// { +// Color[] colors = generateLodColors(lod, x, z, debugging); +// +// addBoundingBoxToBuffer(buffer, bbox, colors); +// } +// } +// } + break; + } // case + } + + + + + private AxisAlignedBB generateBoundingBox(LodChunk lod, int width, double xOffset, double yOffset, double zOffset) + { + int topPoint = lod.getHeight(); + int bottomPoint = lod.getDepth(); // don't add an LOD if it is empty if (topPoint == -1 && bottomPoint == -1) - return; + return null; if (bottomPoint == topPoint) { @@ -47,54 +96,10 @@ public class CubicLodTemplate extends AbstractLodTemplate topPoint++; } - - Color[] colors = generateLodColors(lod, debugging); - - - // Add this LOD to the BufferBuilder - // using the quality setting set by the config - switch(LodConfig.CLIENT.lodGeometryQuality.get()) - { - case SINGLE: - bbox = new AxisAlignedBB(0, bottomPoint, 0, LodChunk.WIDTH, topPoint, LodChunk.WIDTH).offset(xOffset, yOffset, zOffset); - - addBoundingBoxToBuffer(buffer, bbox, colors); - break; - - case SINGLE_CLOSE_QUAD_FAR: - // TODO - break; - - case QUAD: - - int halfWidth = LodChunk.WIDTH / 2; - - addQuarterBoundingBoxToBuffer(buffer, lod, colors, LodCorner.NE, xOffset, yOffset, zOffset); - addQuarterBoundingBoxToBuffer(buffer, lod, colors, LodCorner.NE, xOffset + halfWidth, yOffset, zOffset + halfWidth); - addQuarterBoundingBoxToBuffer(buffer, lod, colors, LodCorner.NE, xOffset + halfWidth, yOffset, zOffset); - addQuarterBoundingBoxToBuffer(buffer, lod, colors, LodCorner.SW, xOffset, yOffset, zOffset + halfWidth); - - break; - - } + return new AxisAlignedBB(0, bottomPoint, 0, width, topPoint, width).offset(xOffset, yOffset, zOffset); } - private void addQuarterBoundingBoxToBuffer(BufferBuilder buffer, LodChunk lod, Color[] c, - LodCorner corner, double xOffset, double yOffset, double zOffset) - { - int topPoint = lod.top[corner.value]; - int bottomPoint = lod.bottom[corner.value]; - int halfWidth = LodChunk.WIDTH / 2; - - if (topPoint != -1 && bottomPoint != -1) - { - AxisAlignedBB bb = new AxisAlignedBB(0, bottomPoint, 0, halfWidth, topPoint, halfWidth) - .offset(xOffset, - yOffset, - zOffset); - addBoundingBoxToBuffer(buffer, bb, c); - } - } + private void addBoundingBoxToBuffer(BufferBuilder buffer, AxisAlignedBB bb, Color[] c) { @@ -135,19 +140,6 @@ public class CubicLodTemplate extends AbstractLodTemplate - /** - * @Returns -1 if there are no valid points - */ - private int getValidHeightPoint(short[] heightPoints) - { - if (heightPoints[LodCorner.NE.value] != -1) - return heightPoints[LodCorner.NE.value]; - if (heightPoints[LodCorner.NW.value] != -1) - return heightPoints[LodCorner.NW.value]; - if (heightPoints[LodCorner.SE.value] != -1) - return heightPoints[LodCorner.NE.value]; - return heightPoints[LodCorner.NE.value]; - } /** @@ -157,7 +149,26 @@ public class CubicLodTemplate extends AbstractLodTemplate { Color[] colors = new Color[ColorDirection.values().length]; - if (debugging) + 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] = lod.getColor(ColorDirection.TOP); + break; + + case INDIVIDUAL_SIDES: + // add each direction's color to the array + for(ColorDirection dir : ColorDirection.values()) + colors[dir.value] = lod.getColor(dir); + break; + } + } + else { // if debugging draw the squares as a black and white checker board if ((lod.x + lod.z) % 2 == 0) @@ -169,26 +180,10 @@ public class CubicLodTemplate extends AbstractLodTemplate for(ColorDirection dir : ColorDirection.values()) colors[dir.value] = debugBlack; } - else - { - // 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] = lod.colors[ColorDirection.TOP.value]; - break; - - case INDIVIDUAL_SIDES: - // add each direction's color to the array - for(ColorDirection dir : ColorDirection.values()) - colors[dir.value] = lod.colors[dir.value]; - break; - } - } return colors; } + + + } diff --git a/src/main/java/com/backsun/lod/objects/LodChunk.java b/src/main/java/com/backsun/lod/objects/LodChunk.java index 3958ca7cb..da6bddbd8 100644 --- a/src/main/java/com/backsun/lod/objects/LodChunk.java +++ b/src/main/java/com/backsun/lod/objects/LodChunk.java @@ -3,8 +3,6 @@ package com.backsun.lod.objects; import java.awt.Color; import com.backsun.lod.enums.ColorDirection; -import com.backsun.lod.enums.LodCorner; -import com.backsun.lod.enums.LodLocation; import net.minecraft.util.math.ChunkPos; @@ -13,102 +11,85 @@ import net.minecraft.util.math.ChunkPos; * and color data for an LOD object. * * @author James Seibel - * @version 03-24-2021 + * @version 05-29-2021 */ public class LodChunk { /** how many different pieces of data are in one line */ - private static final int DATA_DELIMITER_COUNT = 28; + private static final int DATA_DELIMITER_COUNT = 22; /** This is what separates each piece of data in the toData method */ public static final char DATA_DELIMITER = ','; + /** Width of a Minecraft Chunk */ public static final int WIDTH = 16; + private static final Color INVISIBLE = new Color(0,0,0,0); + /** The x coordinate of the chunk. */ - public int x; + public int x = 0; /** The z coordinate of the chunk. */ - public int z; + public int z = 0; - // each short is the height of - // that 8th of the chunk. - public short top[]; - public short bottom[]; + private short height; + private short depth; - /** The average color of each 6 cardinal directions */ + /** The average color for the 6 cardinal directions */ public Color colors[]; - /** If true that means this LodChunk is just a placeholder and - * no LOD has been generated for this chunk location */ - private boolean emptyPlaceholder = false; + /** If true then this LodChunk contains no data */ + private boolean empty = false; - - - - - //==============// - // constructors // - //==============// - /** * Create an empty invisible LodChunk at (0,0) */ public LodChunk() { - emptyPlaceholder = true; + empty = true; x = 0; z = 0; - top = new short[4]; - bottom = new short[4]; - colors = new Color[6]; + height = 0; + depth = 0; + colors = new Color[ColorDirection.values().length]; // by default have the colors invisible for(ColorDirection dir : ColorDirection.values()) - { - colors[dir.value] = new Color(0, 0, 0, 0); - } + colors[dir.value] = INVISIBLE; } + /** * Creates an LodChunk from the string * generated by the toData method. * * @throws IllegalArgumentException if the data isn't valid to create a LodChunk - * @throws NumberFormatException if the data can't be converted into an int at any point + * @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, top data, bottom data, rgb color data + * x, z, height, depth, rgb color data * * example: - * 5,8, 4,4,4,4, 0,0,0,0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, + * 5,8, 4, 0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, */ - emptyPlaceholder = false; - // 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 + "."); - } @@ -123,31 +104,19 @@ public class LodChunk x = Integer.parseInt(data.substring(0,index)); lastIndex = index; - index = data.indexOf(DATA_DELIMITER, lastIndex + 1); + 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); + 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)); - // top - top = new short[4]; - for(LodLocation loc : LodLocation.values()) - { - lastIndex = index; - index = data.indexOf(DATA_DELIMITER, lastIndex + 1); - - top[loc.value] = Short.parseShort(data.substring(lastIndex+1,index)); - } - - - // bottom - bottom = new short[4]; - for(LodLocation loc : LodLocation.values()) - { - lastIndex = index; - index = data.indexOf(DATA_DELIMITER, lastIndex + 1); - - bottom[loc.value] = Short.parseShort(data.substring(lastIndex+1,index)); - } // color @@ -184,21 +153,26 @@ public class LodChunk colors[dir.value] = new Color(red, green, blue); } + + + // after going through all this + // is this LOD empty? + empty = determineIfEmtpy(); } /** * Create a LodChunk from the given values. */ - public LodChunk(ChunkPos pos, short[] newTop, short[] newBottom, Color[] newColors) + public LodChunk(ChunkPos pos, short newHeight, short newDepth, Color[] newColors) { - emptyPlaceholder = false; - x = pos.x; z = pos.z; - top = newTop; - bottom = newBottom; + height = newHeight; + depth = newDepth; colors = newColors; + + empty = determineIfEmtpy(); } @@ -215,27 +189,28 @@ public class LodChunk */ public boolean isPlaceholder() { - return emptyPlaceholder; + return empty; + } + + public boolean isLodEmpty() + { + return empty; } /** * Returns true if this LOD is either invisible - * from every direction, doesn't have a valid height, - * or is an emptyPlaceholder. + * from every direction or doesn't have a valid height. */ - public boolean isLodEmpty() + private boolean determineIfEmtpy() { - if (emptyPlaceholder) - return true; + if(height != -1) + // we don't check the depth since the + // height should always be greater than or equal + // to the depth + return false; - for(LodCorner corner : LodCorner.values()) - if(top[corner.value] != -1 || bottom[corner.value] != -1) - // at least one corner is valid - return false; - - Color invisible = new Color(0,0,0,0); for(ColorDirection dir : ColorDirection.values()) - if(!colors[dir.value].equals(invisible)) + if(!colors[dir.value].equals(INVISIBLE)) // at least one direction has a non-invisible color return false; @@ -245,11 +220,28 @@ public class LodChunk - //========// // output // //========// + /** Returns the color for the given direction */ + public Color getColor(ColorDirection dir) + { + return colors[dir.value]; + } + + public short getHeight() + { + return height; + } + + public short getDepth() + { + return depth; + } + + + /** @@ -258,12 +250,12 @@ public class LodChunk *
* Exports data in the form: *
- * x, z, top data, bottom data, rgb color data + * x, z, height, depth, rgb color data * *
* example output: *
- * 5,8, 4,4,4,4, 0,0,0,0 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, + * 5,8, 4, 0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, */ public String toData() { @@ -271,15 +263,9 @@ public class LodChunk s += Integer.toString(x) + DATA_DELIMITER + Integer.toString(z) + DATA_DELIMITER; - for(int i = 0; i < top.length; i++) - { - s += Short.toString(top[i]) + DATA_DELIMITER; - } + s += Short.toString(height) + DATA_DELIMITER; - for(int i = 0; i < bottom.length; i++) - { - s += Short.toString(bottom[i]) + DATA_DELIMITER; - } + s += Short.toString(depth) + DATA_DELIMITER; for(int i = 0; i < colors.length; i++) {