Add variable detail LODs
This commit is contained in:
@@ -5,7 +5,9 @@ import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import com.seibel.lod.enums.ColorDirection;
|
||||
import com.seibel.lod.enums.LodDetail;
|
||||
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.LodUtils;
|
||||
@@ -26,7 +28,7 @@ import net.minecraft.world.gen.Heightmap;
|
||||
* (specifically: Lod World, Dimension, Region, and Chunk objects)
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 5-29-2021
|
||||
* @version 6-12-2021
|
||||
*/
|
||||
public class LodBuilder
|
||||
{
|
||||
@@ -41,13 +43,6 @@ public class LodBuilder
|
||||
public static final int CHUNK_DATA_WIDTH = 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 = 32;
|
||||
// the max number of blocks per layer = 64 (8*8)
|
||||
|
||||
|
||||
public LodBuilder()
|
||||
@@ -67,7 +62,7 @@ public class LodBuilder
|
||||
// we are not in the same world anymore
|
||||
// don't add this LOD
|
||||
return;
|
||||
|
||||
|
||||
|
||||
// don't try to create an LOD object
|
||||
// if for some reason we aren't
|
||||
@@ -128,33 +123,49 @@ public class LodBuilder
|
||||
throw new IllegalArgumentException("generateLodFromChunk given a null chunk");
|
||||
}
|
||||
|
||||
Color[] colors = new Color[ColorDirection.values().length];
|
||||
LodDetail detail = LodChunk.DETAIL;
|
||||
LodDataPoint[][] dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount];
|
||||
|
||||
|
||||
short height = determineTopPoint(chunk.getSections());
|
||||
short depth = determineBottomPoint(chunk.getSections());
|
||||
|
||||
|
||||
// determine the average color for each direction
|
||||
for(ColorDirection dir : ColorDirection.values())
|
||||
for(int i = 0; i < detail.lengthCount * detail.lengthCount; i++)
|
||||
{
|
||||
colors[dir.value] = generateLodColorForDirection(chunk, dir);
|
||||
int startX = detail.startX[i];
|
||||
int startZ = detail.startZ[i];
|
||||
int endX = detail.endX[i];
|
||||
int endZ = detail.endZ[i];
|
||||
|
||||
|
||||
Color[] colors = new Color[ColorDirection.values().length];
|
||||
|
||||
short height = determineTopPointForArea(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);
|
||||
}
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
return new LodChunk(chunk.getPos(), height, depth, colors);
|
||||
return new LodChunk(chunk.getPos(), dataPoints);
|
||||
}
|
||||
|
||||
|
||||
@@ -169,21 +180,42 @@ public class LodBuilder
|
||||
|
||||
/**
|
||||
* Find the lowest valid point from the bottom.
|
||||
* @param chunkSections
|
||||
* @param startX
|
||||
* @param startZ
|
||||
* @param endX
|
||||
* @param endZ
|
||||
*/
|
||||
private short determineBottomPoint(ChunkSection[] chunkSections)
|
||||
private short determineBottomPointForArea(ChunkSection[] chunkSections,
|
||||
int startX, int startZ, int endX, int endZ)
|
||||
{
|
||||
int numberOfBlocksRequired = ((endX-startX) * (endZ-startZ) / 2);
|
||||
|
||||
// search from the bottom up
|
||||
for(int i = 0; i < CHUNK_DATA_WIDTH; i++)
|
||||
for(int section = 0; section < CHUNK_DATA_WIDTH; section++)
|
||||
{
|
||||
for(int y = 0; y < CHUNK_SECTION_HEIGHT; y++)
|
||||
{
|
||||
if(isLayerValidLodPoint(chunkSections, i, y))
|
||||
int numberOfBlocksFound = 0;
|
||||
|
||||
for(int x = startX; x < endX; x++)
|
||||
{
|
||||
// we found
|
||||
// enough blocks in this
|
||||
// layer to count as an
|
||||
// LOD point
|
||||
return (short) (y + (i * CHUNK_SECTION_HEIGHT));
|
||||
for(int z = startZ; z < endZ; z++)
|
||||
{
|
||||
if(isLayerValidLodPoint(chunkSections, section, y, x, z))
|
||||
{
|
||||
numberOfBlocksFound++;
|
||||
|
||||
if (numberOfBlocksFound >= numberOfBlocksRequired)
|
||||
{
|
||||
// we found
|
||||
// enough blocks in this
|
||||
// layer to count as an
|
||||
// LOD point
|
||||
return (short) (y + (section * CHUNK_SECTION_HEIGHT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,21 +239,42 @@ public class LodBuilder
|
||||
|
||||
/**
|
||||
* Find the highest valid point from the Top
|
||||
* @param chunkSections
|
||||
* @param startX
|
||||
* @param startZ
|
||||
* @param endX
|
||||
* @param endZ
|
||||
*/
|
||||
private short determineTopPoint(ChunkSection[] chunkSections)
|
||||
private short determineTopPointForArea(ChunkSection[] chunkSections,
|
||||
int startX, int startZ, int endX, int endZ)
|
||||
{
|
||||
int numberOfBlocksRequired = ((endX-startX) * (endZ-startZ) / 2);
|
||||
|
||||
// search from the top down
|
||||
for(int section = chunkSections.length - 1; section >= 0; section--)
|
||||
{
|
||||
for(int y = CHUNK_DATA_WIDTH - 1; y >= 0; y--)
|
||||
{
|
||||
if(isLayerValidLodPoint(chunkSections, section, y))
|
||||
int numberOfBlocksFound = 0;
|
||||
|
||||
for(int x = startX; x < endX; x++)
|
||||
{
|
||||
// we found
|
||||
// enough blocks in this
|
||||
// layer to count as an
|
||||
// LOD point
|
||||
return (short) (y + (section * CHUNK_SECTION_HEIGHT));
|
||||
for(int z = startZ; z < endZ; z++)
|
||||
{
|
||||
if(isLayerValidLodPoint(chunkSections, section, y, x, z))
|
||||
{
|
||||
numberOfBlocksFound++;
|
||||
|
||||
if (numberOfBlocksFound >= numberOfBlocksRequired)
|
||||
{
|
||||
// we found
|
||||
// enough blocks in this
|
||||
// layer to count as an
|
||||
// LOD point
|
||||
return (short) (y + (section * CHUNK_SECTION_HEIGHT));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -253,7 +306,7 @@ public class LodBuilder
|
||||
/**
|
||||
* Generate the color for the given chunk in the given ColorDirection.
|
||||
*/
|
||||
private Color generateLodColorForDirection(IChunk chunk, ColorDirection colorDir)
|
||||
private Color generateLodColorForAreaInDirection(IChunk chunk, ColorDirection colorDir, int startX, int startZ, int endX, int endZ)
|
||||
{
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
BlockColors bc = mc.getBlockColors();
|
||||
@@ -261,19 +314,20 @@ public class LodBuilder
|
||||
switch (colorDir)
|
||||
{
|
||||
case TOP:
|
||||
return generateLodColorVertical(chunk, colorDir, bc);
|
||||
return generateLodColorVerticalOverArea(chunk, colorDir, bc, startX, startZ, endX, endZ);
|
||||
case BOTTOM:
|
||||
return generateLodColorVertical(chunk, colorDir, bc);
|
||||
return generateLodColorVerticalOverArea(chunk, colorDir, bc, startX, startZ, endX, endZ);
|
||||
|
||||
// TODO
|
||||
case NORTH:
|
||||
return generateLodColorHorizontal(chunk, colorDir, bc);
|
||||
return generateLodColorHorizontalOverArea(chunk, colorDir, bc);
|
||||
case SOUTH:
|
||||
return generateLodColorHorizontal(chunk, colorDir, bc);
|
||||
return generateLodColorHorizontalOverArea(chunk, colorDir, bc);
|
||||
|
||||
case EAST:
|
||||
return generateLodColorHorizontal(chunk, colorDir, bc);
|
||||
return generateLodColorHorizontalOverArea(chunk, colorDir, bc);
|
||||
case WEST:
|
||||
return generateLodColorHorizontal(chunk, colorDir, bc);
|
||||
return generateLodColorHorizontalOverArea(chunk, colorDir, bc);
|
||||
}
|
||||
|
||||
return INVISIBLE;
|
||||
@@ -290,39 +344,23 @@ public class LodBuilder
|
||||
*/
|
||||
private boolean isLayerValidLodPoint(
|
||||
ChunkSection[] chunkSections,
|
||||
int sectionIndex, int y)
|
||||
int sectionIndex, int y,
|
||||
int x, int z)
|
||||
{
|
||||
// search through this layer
|
||||
int layerBlocks = 0;
|
||||
|
||||
for(int x = 0; x < LodChunk.WIDTH; x++)
|
||||
if(chunkSections[sectionIndex] == null)
|
||||
{
|
||||
for(int z = 0; z < LodChunk.WIDTH; z++)
|
||||
// this section doesn't have any blocks,
|
||||
// it is not a valid section
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(chunkSections[sectionIndex].getBlockState(x, y, z) != null &&
|
||||
chunkSections[sectionIndex].getBlockState(x, y, z).getBlock() != Blocks.AIR)
|
||||
{
|
||||
if(chunkSections[sectionIndex] == null)
|
||||
{
|
||||
// this section doesn't have any blocks,
|
||||
// it is not a valid section
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
layerBlocks++;
|
||||
|
||||
if(layerBlocks >= LOD_BLOCK_REQ)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // z
|
||||
} // x
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -332,7 +370,9 @@ public class LodBuilder
|
||||
*
|
||||
* @throws IllegalArgumentException if given a ColorDirection other than TOP or BOTTOM
|
||||
*/
|
||||
private Color generateLodColorVertical(IChunk chunk, ColorDirection colorDir, BlockColors bc)
|
||||
private Color generateLodColorVerticalOverArea(
|
||||
IChunk chunk, ColorDirection colorDir, BlockColors bc,
|
||||
int startX, int startZ, int endX, int endZ)
|
||||
{
|
||||
if(colorDir != ColorDirection.TOP && colorDir != ColorDirection.BOTTOM)
|
||||
{
|
||||
@@ -362,9 +402,9 @@ public class LodBuilder
|
||||
int topMin = 0;
|
||||
int topIncrement = goTopDown? -1 : 1;
|
||||
|
||||
for(int x = 0; x < CHUNK_DATA_WIDTH; x++)
|
||||
for(int x = startX; x < endX; x++)
|
||||
{
|
||||
for(int z = 0; z < CHUNK_DATA_WIDTH; z++)
|
||||
for(int z = startZ; z < endZ; z++)
|
||||
{
|
||||
boolean foundBlock = false;
|
||||
|
||||
@@ -446,7 +486,8 @@ public class LodBuilder
|
||||
/**
|
||||
* Generates the color for the sides of the given chunk.
|
||||
*/
|
||||
private Color generateLodColorHorizontal(IChunk chunk, ColorDirection colorDir, BlockColors bc)
|
||||
private Color generateLodColorHorizontalOverArea(
|
||||
IChunk chunk, ColorDirection colorDir, BlockColors bc)
|
||||
{
|
||||
if(colorDir != ColorDirection.NORTH && colorDir != ColorDirection.SOUTH && colorDir != ColorDirection.EAST && colorDir != ColorDirection.WEST)
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ import net.minecraftforge.common.WorldWorkerManager.IWorker;
|
||||
* This is used to generate a LodChunk at a given ChunkPos.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 03-31-2021
|
||||
* @version 6-12-2021
|
||||
*/
|
||||
public class LodChunkGenWorker implements IWorker
|
||||
{
|
||||
@@ -54,7 +54,7 @@ public class LodChunkGenWorker implements IWorker
|
||||
// be added to the current LodDimension
|
||||
if (lodDim.regionIsInRange(pos.x / LodRegion.SIZE, pos.z / LodRegion.SIZE))
|
||||
{
|
||||
IChunk chunk;// = serverWorld.getChunk(x, z, ChunkStatus.EMPTY, true);
|
||||
IChunk chunk;
|
||||
|
||||
//long startTime = System.currentTimeMillis();
|
||||
chunk = serverWorld.getChunk(x, z, ChunkStatus.FEATURES);
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package com.seibel.lod.builders.lodTemplates;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import com.seibel.lod.objects.LodChunk;
|
||||
import com.seibel.lod.objects.LodDimension;
|
||||
|
||||
@@ -12,16 +10,10 @@ import net.minecraft.client.renderer.BufferBuilder;
|
||||
* BufferBuilders.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 05-07-2021
|
||||
* @version 06-12-2021
|
||||
*/
|
||||
public abstract class AbstractLodTemplate
|
||||
{
|
||||
/** alpha used when drawing chunks in debug mode */
|
||||
protected int debugAlpha = 255; // 0 - 255
|
||||
protected Color debugBlack = new Color(0, 0, 0, debugAlpha);
|
||||
protected Color debugWhite = new Color(255, 255, 255, debugAlpha);
|
||||
|
||||
|
||||
public abstract void addLodToBuffer(BufferBuilder buffer,
|
||||
LodDimension lodDim, LodChunk lod,
|
||||
double xOffset, double yOffset, double zOffset,
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package com.seibel.lod.builders.lodTemplates;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.EnumSet;
|
||||
|
||||
import com.seibel.lod.enums.ColorDirection;
|
||||
import com.seibel.lod.enums.RelativeChunkPos;
|
||||
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;
|
||||
@@ -16,7 +14,7 @@ import net.minecraft.util.math.AxisAlignedBB;
|
||||
* Builds LODs as rectangular prisms.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 05-31-2021
|
||||
* @version 06-12-2021
|
||||
*/
|
||||
public class CubicLodTemplate extends AbstractLodTemplate
|
||||
{
|
||||
@@ -37,118 +35,34 @@ public class CubicLodTemplate extends AbstractLodTemplate
|
||||
|
||||
// Add this LOD to the BufferBuilder
|
||||
// using the quality setting set by the config
|
||||
switch(LodConfig.CLIENT.lodDetail.get())
|
||||
LodDetail detail = LodChunk.DETAIL; //LodConfig.CLIENT.lodDetail.get();
|
||||
|
||||
int halfWidth = detail.width / 2;
|
||||
|
||||
for(int i = 0; i < detail.lengthCount * detail.lengthCount; i++)
|
||||
{
|
||||
// add a single LOD object for this chunk
|
||||
case SINGLE:
|
||||
int startX = detail.startX[i];
|
||||
int startZ = detail.startZ[i];
|
||||
int endX = detail.endX[i];
|
||||
int endZ = detail.endZ[i];
|
||||
|
||||
// returns null if the lod is empty at the given location
|
||||
bbox = generateBoundingBox(centerLod.getHeight(), centerLod.getDepth(), LodChunk.WIDTH, xOffset, yOffset, zOffset);
|
||||
bbox = generateBoundingBox(
|
||||
centerLod.getAverageHeightOverArea(startX, startZ, endX, endZ),
|
||||
centerLod.getAverageDepthOverArea(startX, startZ, endX, endZ),
|
||||
detail.width,
|
||||
xOffset - (halfWidth / 2) + detail.startX[i],
|
||||
yOffset,
|
||||
zOffset - (halfWidth / 2) + detail.startZ[i]);
|
||||
|
||||
if (bbox != null)
|
||||
{
|
||||
addBoundingBoxToBuffer(buffer, bbox, generateLodColors(centerLod, false));
|
||||
addBoundingBoxToBuffer(buffer, bbox, centerLod.getAverageColorOverArea(startX, startZ, endX, endZ, debugging));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// add 4 LOD objects for this chunk
|
||||
case DOUBLE:
|
||||
/*
|
||||
* This method generates LODs using the LodChunks that
|
||||
* are adjacent to create an average quarter and thus
|
||||
* smooth the transition between chunks.
|
||||
*/
|
||||
|
||||
// get the adjacent LodChunks
|
||||
LodChunk[] lods = new LodChunk[RelativeChunkPos.values().length];
|
||||
for(RelativeChunkPos pos : RelativeChunkPos.values())
|
||||
lods[pos.index] = lodDim.getLodFromCoordinates(centerLod.x + pos.x, centerLod.z + pos.z);
|
||||
|
||||
|
||||
int halfWidth = LodChunk.WIDTH / 2;
|
||||
|
||||
// use the adjacent chunks to generate quarter sections
|
||||
for(EnumSet<RelativeChunkPos> set : RelativeChunkPos.CORNERS)
|
||||
{
|
||||
int x = 0;
|
||||
int z = 0;
|
||||
|
||||
// Weight the center LodChunk by this amount
|
||||
// when taking the average.
|
||||
// this should be between 3 and 6;
|
||||
// if set to 1 (no extra weight)
|
||||
// then the chunks don't appear to be averaged.
|
||||
int centerWeight = 3;
|
||||
|
||||
// how many LodChunks adjacent to the center
|
||||
// are valid?
|
||||
int validPoints = centerWeight;
|
||||
|
||||
int avgHeight = centerLod.getHeight() * centerWeight;
|
||||
int avgDepth = centerLod.getDepth() * centerWeight;
|
||||
|
||||
int[][] colorAverages = new int[ColorDirection.values().length][3];
|
||||
Color[] colorToAdd = generateLodColors(centerLod, debugging);
|
||||
for(int i = 0; i < centerWeight; i++)
|
||||
colorAverages = addColorToColorAverages(colorAverages, colorToAdd);
|
||||
|
||||
for(RelativeChunkPos cornerPos : set)
|
||||
{
|
||||
// set the x and y location based on which
|
||||
// corner we are working on
|
||||
if (RelativeChunkPos.DIAGONAL.contains(cornerPos))
|
||||
{
|
||||
x = Math.min(cornerPos.x, 0) * halfWidth;
|
||||
z = Math.min(cornerPos.z, 0) * halfWidth;
|
||||
}
|
||||
|
||||
LodChunk cornerLod = lods[cornerPos.index];
|
||||
if (cornerLod != null && !cornerLod.isLodEmpty())
|
||||
{
|
||||
validPoints++;
|
||||
|
||||
avgHeight += cornerLod.getHeight();
|
||||
avgDepth += cornerLod.getDepth();
|
||||
|
||||
// only generate average colors if we aren't debugging
|
||||
// (this is to prevent everything from becoming grey)
|
||||
if (!debugging)
|
||||
colorToAdd = generateLodColors(cornerLod, debugging);
|
||||
else
|
||||
colorToAdd = generateLodColors(centerLod, debugging);
|
||||
// add to the running color average
|
||||
colorAverages = addColorToColorAverages(colorAverages, colorToAdd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// convert the heights into actual averages
|
||||
avgHeight /= validPoints;
|
||||
avgDepth /= validPoints;
|
||||
// calculate the average colors
|
||||
Color[] colors = new Color[ColorDirection.values().length];
|
||||
for(ColorDirection dir : ColorDirection.values())
|
||||
{
|
||||
for(int rgbIndex = 0; rgbIndex < 3; rgbIndex++)
|
||||
colorAverages[dir.value][rgbIndex] /= validPoints;
|
||||
colors[dir.value] = new Color(colorAverages[dir.value][0], colorAverages[dir.value][1], colorAverages[dir.value][2]);
|
||||
}
|
||||
|
||||
|
||||
// returns null if the lod is empty at the given location
|
||||
bbox = generateBoundingBox(avgHeight, avgDepth, halfWidth, xOffset - (halfWidth / 2) + x + 12, yOffset, zOffset - (halfWidth / 2) + z + 12);
|
||||
|
||||
if (bbox != null)
|
||||
{
|
||||
addBoundingBoxToBuffer(buffer, bbox, colors);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} // case
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
private int[][] addColorToColorAverages(int[][] colorAverages, Color[] colorToAdd)
|
||||
{
|
||||
for(ColorDirection dir : ColorDirection.values())
|
||||
@@ -167,7 +81,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
|
||||
|
||||
return colorAverages;
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -228,50 +142,4 @@ public class CubicLodTemplate extends AbstractLodTemplate
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Determine the color for each side of this LOD.
|
||||
*/
|
||||
private Color[] generateLodColors(LodChunk lod, boolean debugging)
|
||||
{
|
||||
Color[] colors = new Color[ColorDirection.values().length];
|
||||
|
||||
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)
|
||||
for(ColorDirection dir : ColorDirection.values())
|
||||
// have each direction be the same
|
||||
// color if debugging
|
||||
colors[dir.value] = debugWhite;
|
||||
else
|
||||
for(ColorDirection dir : ColorDirection.values())
|
||||
colors[dir.value] = debugBlack;
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.seibel.lod.enums;
|
||||
|
||||
import com.seibel.lod.objects.LodChunk;
|
||||
|
||||
/**
|
||||
* single, quad
|
||||
* single, double, quad, half, full
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 05-29-2021
|
||||
* @version 06-12-2021
|
||||
*/
|
||||
public enum LodDetail
|
||||
{
|
||||
@@ -12,14 +14,72 @@ public enum LodDetail
|
||||
SINGLE(1),
|
||||
|
||||
/** render 4 LODs for each chunk */
|
||||
DOUBLE(2);
|
||||
DOUBLE(2),
|
||||
|
||||
/** How many data points wide the related
|
||||
* LodChunk object should contain */
|
||||
public final int value;
|
||||
/** render 16 LODs for each chunk */
|
||||
QUAD(4),
|
||||
|
||||
private LodDetail(int newValue)
|
||||
/** render 64 LODs for each chunk */
|
||||
HALF(8),
|
||||
|
||||
/** render 256 LODs for each chunk */
|
||||
FULL(16);
|
||||
|
||||
|
||||
/** How many LODs wide should
|
||||
* be drawn per LodChunk */
|
||||
public final int lengthCount;
|
||||
/** How wide each LOD is */
|
||||
public final int width;
|
||||
|
||||
/* */
|
||||
public final int[] startX;
|
||||
public final int[] startZ;
|
||||
|
||||
public final int[] endX;
|
||||
public final int[] endZ;
|
||||
|
||||
|
||||
private LodDetail(int newLengthCount)
|
||||
{
|
||||
value = newValue;
|
||||
lengthCount = newLengthCount;
|
||||
width = 16 / lengthCount;
|
||||
|
||||
if(newLengthCount == LodChunk.WIDTH)
|
||||
{
|
||||
// this is to prevent overflow
|
||||
newLengthCount = LodChunk.WIDTH - 1;
|
||||
}
|
||||
|
||||
startX = new int[lengthCount * lengthCount];
|
||||
endX = new int[lengthCount * lengthCount];
|
||||
|
||||
startZ = new int[lengthCount * lengthCount];
|
||||
endZ = new int[lengthCount * lengthCount];
|
||||
|
||||
|
||||
int index = 0;
|
||||
for(int x = 0; x < newLengthCount; x++)
|
||||
{
|
||||
for(int z = 0; z < newLengthCount; z++)
|
||||
{
|
||||
startX[index] = x * width;
|
||||
startZ[index] = z * width;
|
||||
|
||||
// special case for FULL
|
||||
if(width != 1)
|
||||
{
|
||||
endX[index] = (x*width) + width - 1;
|
||||
endZ[index] = (z*width) + width - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
endX[index] = (x*width) + width;
|
||||
endZ[index] = (z*width) + width;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,10 +19,14 @@ import com.seibel.lod.proxy.ClientProxy;
|
||||
* to file.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 05-31-2021
|
||||
* @version 6-12-2021
|
||||
*/
|
||||
public class LodDimensionFileHandler
|
||||
{
|
||||
/** This is what separates each piece of data */
|
||||
public static final char DATA_DELIMITER = ',';
|
||||
|
||||
|
||||
private LodDimension loadedDimension = null;
|
||||
public long regionLastWriteTime[][];
|
||||
|
||||
@@ -74,6 +78,9 @@ public class LodDimensionFileHandler
|
||||
*/
|
||||
public LodRegion loadRegionFromFile(int regionX, int regionZ)
|
||||
{
|
||||
// TODO
|
||||
return null;
|
||||
/*
|
||||
String fileName = getFileNameAndPathForRegion(regionX, regionZ);
|
||||
|
||||
File f = new File(fileName);
|
||||
@@ -174,6 +181,7 @@ public class LodDimensionFileHandler
|
||||
}
|
||||
|
||||
return region;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
@@ -192,7 +200,8 @@ public class LodDimensionFileHandler
|
||||
*/
|
||||
public void saveDirtyRegionsToFileAsync()
|
||||
{
|
||||
fileWritingThreadPool.execute(saveDirtyRegionsThread);
|
||||
// TODO
|
||||
//fileWritingThreadPool.execute(saveDirtyRegionsThread);
|
||||
}
|
||||
|
||||
private Thread saveDirtyRegionsThread = new Thread(() ->
|
||||
|
||||
@@ -3,6 +3,9 @@ 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;
|
||||
|
||||
@@ -11,7 +14,7 @@ import net.minecraft.util.math.ChunkPos;
|
||||
* and color data for an LOD object.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 05-29-2021
|
||||
* @version 6-12-2021
|
||||
*/
|
||||
public class LodChunk
|
||||
{
|
||||
@@ -19,39 +22,29 @@ public class LodChunk
|
||||
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 = ',';
|
||||
private static final char DATA_DELIMITER = LodDimensionFileHandler.DATA_DELIMITER;
|
||||
|
||||
/** Width of a Minecraft Chunk */
|
||||
public static final int WIDTH = 16;
|
||||
|
||||
/** alpha used when drawing chunks in debug mode */
|
||||
private static final int DEBUG_ALPHA = 255; // 0 - 255
|
||||
private static final Color DEBUG_BLACK = new Color(0, 0, 0, DEBUG_ALPHA);
|
||||
private static final Color DEBUG_WHITE = new Color(255, 255, 255, DEBUG_ALPHA);
|
||||
private static final Color INVISIBLE = new Color(0,0,0,0);
|
||||
|
||||
|
||||
public static final LodDetail DETAIL = LodDetail.QUAD;
|
||||
|
||||
|
||||
/** The x coordinate of the chunk. */
|
||||
public int x = 0;
|
||||
/** The z coordinate of the chunk. */
|
||||
public int z = 0;
|
||||
|
||||
/*
|
||||
* The reason we are only using 1 height and depth point
|
||||
* instead of multiple is because:
|
||||
* 1. more points would drastically increase the amount of
|
||||
* memory and disk space needed
|
||||
* 2. more height/depth points require more color points,
|
||||
* which can get out of hand quickly
|
||||
* 3. with the increased disk space reading/writing would
|
||||
* take far too long
|
||||
* 4. the increased resolution is generally not worth it,
|
||||
* 4 LODs per chunk is the limit of diminishing returns.
|
||||
* And some of that could potentially be faked through
|
||||
* smart LodTemplates
|
||||
*/
|
||||
private short height;
|
||||
private short depth;
|
||||
|
||||
/** The average color for the 6 cardinal directions */
|
||||
public Color colors[];
|
||||
/** This stores the height and color for each data point in the LodChunk */
|
||||
public LodDataPoint dataPoints[][];
|
||||
|
||||
/** If true then this LodChunk contains no data */
|
||||
private boolean empty = false;
|
||||
@@ -67,16 +60,11 @@ public class LodChunk
|
||||
x = 0;
|
||||
z = 0;
|
||||
|
||||
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;
|
||||
dataPoints = new LodDataPoint[DETAIL.lengthCount][DETAIL.lengthCount];
|
||||
}
|
||||
|
||||
|
||||
// TODO
|
||||
/**
|
||||
* Creates an LodChunk from the string
|
||||
* generated by the toData method.
|
||||
@@ -84,107 +72,107 @@ 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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
colors[dir.value] = new Color(red, green, blue);
|
||||
}
|
||||
|
||||
|
||||
// after going through all this
|
||||
// is this LOD empty?
|
||||
empty = determineIfEmtpy();
|
||||
}
|
||||
// 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();
|
||||
// }
|
||||
|
||||
/**
|
||||
* Create a LodChunk from the given values.
|
||||
*/
|
||||
public LodChunk(ChunkPos pos, short newHeight, short newDepth, Color[] newColors)
|
||||
public LodChunk(ChunkPos pos, LodDataPoint[][] newDataPoints)
|
||||
{
|
||||
x = pos.x;
|
||||
z = pos.z;
|
||||
|
||||
height = newHeight;
|
||||
depth = newDepth;
|
||||
colors = newColors;
|
||||
dataPoints = newDataPoints;
|
||||
|
||||
empty = determineIfEmtpy();
|
||||
}
|
||||
@@ -217,27 +205,30 @@ public class LodChunk
|
||||
*/
|
||||
private boolean determineIfEmtpy()
|
||||
{
|
||||
// we don't check the depth since the
|
||||
// height should always be greater than or equal
|
||||
// to the depth
|
||||
if(height >= 0)
|
||||
for(LodDataPoint[] dataPointArray : dataPoints)
|
||||
{
|
||||
// the height is valid,
|
||||
// do we have at least 1 non-invisible color?
|
||||
|
||||
for(ColorDirection dir : ColorDirection.values())
|
||||
if(!colors[dir.value].equals(INVISIBLE))
|
||||
// at least one direction has a non-invisible color
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// the height is negative,
|
||||
// this LodChunk is empty
|
||||
return true;
|
||||
for(LodDataPoint dataPoint : dataPointArray)
|
||||
{
|
||||
if (dataPoint == null)
|
||||
continue;
|
||||
|
||||
// we don't check the depth since the
|
||||
// height should always be greater than or equal
|
||||
// to the depth
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// we checked everywhere, this LodChunk is empty
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -247,28 +238,124 @@ public class LodChunk
|
||||
// output //
|
||||
//========//
|
||||
|
||||
/**
|
||||
* Returns the data point for the given relative block position.
|
||||
*/
|
||||
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];
|
||||
}
|
||||
|
||||
/** Returns the color for the given direction */
|
||||
public Color getColor(ColorDirection dir)
|
||||
public Color getColorForBlockPos(int blockX, int blockZ, ColorDirection dir)
|
||||
{
|
||||
return colors[dir.value];
|
||||
return getDataPointForBlockPos(blockX, blockZ).colors[dir.value];
|
||||
}
|
||||
|
||||
public short getHeight()
|
||||
public short getHeightForBlockPos(int blockX, int blockZ)
|
||||
{
|
||||
return height;
|
||||
return getDataPointForBlockPos(blockX, blockZ).height;
|
||||
}
|
||||
|
||||
public short getDepth()
|
||||
public short getDepthForBlockPos(int blockX, int blockZ)
|
||||
{
|
||||
return depth;
|
||||
return getDataPointForBlockPos(blockX, blockZ).depth;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param startX
|
||||
* @param startZ
|
||||
* @param endX
|
||||
* @param endZ
|
||||
* @return
|
||||
*/
|
||||
public short getAverageHeightOverArea(int startX, int startZ, int endX, int endZ)
|
||||
{
|
||||
int average = 0;
|
||||
|
||||
for(int x = startX; x < endX; x++)
|
||||
for(int z = startZ; z < endZ; z++)
|
||||
average += getHeightForBlockPos(x,z);
|
||||
|
||||
return (short) (average / ((endX - startX) * (endZ - startZ)));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param startX
|
||||
* @param startZ
|
||||
* @param endX
|
||||
* @param endZ
|
||||
* @return
|
||||
*/
|
||||
public short getAverageDepthOverArea(int startX, int startZ, int endX, int endZ)
|
||||
{
|
||||
int average = 0;
|
||||
|
||||
for(int x = startX; x < endX; x++)
|
||||
for(int z = startZ; z < endZ; z++)
|
||||
average += getDepthForBlockPos(x,z);
|
||||
|
||||
return (short) (average / ((endX - startX) * (endZ - startZ)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine the color for each side of this LOD.
|
||||
*/
|
||||
public Color[] getAverageColorOverArea(int startX, int startZ, int endX, int endZ, boolean debugging)
|
||||
{
|
||||
Color[] colors = new Color[ColorDirection.values().length];
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return colors;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Outputs all data in csv format
|
||||
* Outputs all data in a csv format
|
||||
* with the given delimiter.
|
||||
* <br>
|
||||
* Exports data in the form:
|
||||
@@ -286,14 +373,9 @@ public class LodChunk
|
||||
|
||||
s += Integer.toString(x) + DATA_DELIMITER + Integer.toString(z) + DATA_DELIMITER;
|
||||
|
||||
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;
|
||||
}
|
||||
for (LodDataPoint[] dataPointArray : dataPoints)
|
||||
for(LodDataPoint dataPoint : dataPointArray)
|
||||
s += dataPoint.toData();
|
||||
|
||||
return s;
|
||||
}
|
||||
@@ -306,7 +388,8 @@ public class LodChunk
|
||||
|
||||
s += "x: " + x + " z: " + z + "\t";
|
||||
|
||||
s += "(" + colors[ColorDirection.TOP.value].getRed() + ", " + colors[ColorDirection.TOP.value].getGreen() + ", " + colors[ColorDirection.TOP.value].getBlue() + ")";
|
||||
// TODO
|
||||
//s += "(" + colors[ColorDirection.TOP.value].getRed() + ", " + colors[ColorDirection.TOP.value].getGreen() + ", " + colors[ColorDirection.TOP.value].getBlue() + ")";
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.seibel.lod.objects;
|
||||
|
||||
import java.awt.Color;
|
||||
|
||||
import com.seibel.lod.enums.ColorDirection;
|
||||
import com.seibel.lod.handlers.LodDimensionFileHandler;
|
||||
|
||||
/**
|
||||
* This stores the height and color
|
||||
* for a specific area in a LodChunk.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 6-12-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;
|
||||
|
||||
private static final Color INVISIBLE = new Color(0,0,0,0);
|
||||
|
||||
/** highest point */
|
||||
public short height;
|
||||
|
||||
/** lowest point */
|
||||
public short depth;
|
||||
|
||||
/** The average color for the 6 cardinal directions */
|
||||
public Color colors[];
|
||||
|
||||
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
public LodDataPoint(short newHeight, short newDepth, Color[] newColors)
|
||||
{
|
||||
height = newHeight;
|
||||
depth = newDepth;
|
||||
colors = newColors;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Outputs all data in a csv format
|
||||
* with the given delimiter.
|
||||
* <br>
|
||||
* Exports data in the form:
|
||||
* <br>
|
||||
* height, depth, rgb color data
|
||||
*
|
||||
* <br>
|
||||
* example output:
|
||||
* <br>
|
||||
* 4, 0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 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;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ package com.seibel.lod.objects;
|
||||
* one file in the file system.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 1-22-2021
|
||||
* @version 6-12-2021
|
||||
*/
|
||||
public class LodRegion
|
||||
{
|
||||
@@ -61,9 +61,6 @@ public class LodRegion
|
||||
int arrayX = Math.abs(chunkX % SIZE);
|
||||
int arrayZ = Math.abs(chunkZ % SIZE);
|
||||
|
||||
if(arrayX >= SIZE || arrayZ >= SIZE)
|
||||
return null;
|
||||
|
||||
return chunks[arrayX][arrayZ];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user