Improve and simplify LodChunk

This commit is contained in:
James Seibel
2021-05-29 13:00:43 -05:00
parent 5002db15d6
commit 811e24ee5e
3 changed files with 243 additions and 341 deletions
@@ -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. <br>
* 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.
* <br><br>
* 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.
*/
@@ -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;
}
}
@@ -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
* <br>
* Exports data in the form:
* <br>
* x, z, top data, bottom data, rgb color data
* x, z, height, depth, rgb color data
*
* <br>
* example output:
* <br>
* 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++)
{