Improve and simplify LodChunk
This commit is contained in:
@@ -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++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user