Add variably detailed LodChunks

This commit is contained in:
James Seibel
2021-06-13 19:59:25 -05:00
parent d3231a480d
commit 79ee23e0b0
8 changed files with 281 additions and 285 deletions
@@ -10,6 +10,7 @@ import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.objects.LodDataPoint;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodWorld;
import com.seibel.lod.util.LodConfig;
import com.seibel.lod.util.LodUtils;
import net.minecraft.block.BlockState;
@@ -28,7 +29,7 @@ import net.minecraft.world.gen.Heightmap;
* (specifically: Lod World, Dimension, Region, and Chunk objects)
*
* @author James Seibel
* @version 6-12-2021
* @version 6-13-2021
*/
public class LodBuilder
{
@@ -119,11 +120,10 @@ public class LodBuilder
public LodChunk generateLodFromChunk(IChunk chunk) throws IllegalArgumentException
{
if(chunk == null)
{
throw new IllegalArgumentException("generateLodFromChunk given a null chunk");
}
LodDetail detail = LodChunk.DETAIL;
LodDetail detail = LodConfig.CLIENT.lodDetail.get();
LodDataPoint[][] dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount];
for(int i = 0; i < detail.lengthCount * detail.lengthCount; i++)
@@ -134,35 +134,15 @@ public class LodBuilder
int endZ = detail.endZ[i];
Color[] colors = new Color[ColorDirection.values().length];
Color color = generateLodColorForAreaInDirection(chunk, ColorDirection.TOP, startX, startZ, endX, endZ);
short height = determineTopPointForArea(chunk.getSections(), startX, startZ, endX, endZ);
short height = determineHeightPointForArea(chunk.getSections(), startX, startZ, endX, endZ);
short depth = determineBottomPointForArea(chunk.getSections(), startX, startZ, endX, endZ);
// determine the average color for each direction
for(ColorDirection dir : ColorDirection.values())
{
colors[dir.value] = generateLodColorForAreaInDirection(chunk, dir, startX, startZ, endX, endZ);
}
// check to see if there are any invisible sides
for(ColorDirection dir : ColorDirection.values())
{
// if there are any invisible sides
// replace them with the top side
// (this is done to make sure oceans and other totally
// flat locations have the correct side colors)
if (dir == ColorDirection.BOTTOM || dir == ColorDirection.TOP)
continue;
if (colors[dir.value] == INVISIBLE)
colors[dir.value] = colors[ColorDirection.TOP.value];
}
int x = i / detail.lengthCount;
int z = i % detail.lengthCount;
dataPoints[x][z] = new LodDataPoint(height, depth, colors);
dataPoints[x][z] = new LodDataPoint(height, depth, color);
}
return new LodChunk(chunk.getPos(), dataPoints);
@@ -245,7 +225,7 @@ public class LodBuilder
* @param endX
* @param endZ
*/
private short determineTopPointForArea(ChunkSection[] chunkSections,
private short determineHeightPointForArea(ChunkSection[] chunkSections,
int startX, int startZ, int endX, int endZ)
{
int numberOfBlocksRequired = ((endX-startX) * (endZ-startZ) / 2);
@@ -287,7 +267,7 @@ public class LodBuilder
* Find the highest point from the Top
*/
@SuppressWarnings("unused")
private short determineTopPoint(Heightmap heightmap, int endZ)
private short determineHeightPoint(Heightmap heightmap, int endZ)
{
short highest = 0;
for(int x = 0; x < LodChunk.WIDTH; x++)
@@ -305,6 +285,8 @@ public class LodBuilder
/**
* Generate the color for the given chunk in the given ColorDirection.
* NOTE: only vertical is currently implemented for area,
* the horizontal colors will always be the same regardless of the area.
*/
private Color generateLodColorForAreaInDirection(IChunk chunk, ColorDirection colorDir, int startX, int startZ, int endX, int endZ)
{
@@ -318,16 +300,15 @@ public class LodBuilder
case BOTTOM:
return generateLodColorVerticalOverArea(chunk, colorDir, bc, startX, startZ, endX, endZ);
// TODO
case NORTH:
return generateLodColorHorizontalOverArea(chunk, colorDir, bc);
return generateLodColorHorizontal(chunk, colorDir, bc);
case SOUTH:
return generateLodColorHorizontalOverArea(chunk, colorDir, bc);
return generateLodColorHorizontal(chunk, colorDir, bc);
case EAST:
return generateLodColorHorizontalOverArea(chunk, colorDir, bc);
return generateLodColorHorizontal(chunk, colorDir, bc);
case WEST:
return generateLodColorHorizontalOverArea(chunk, colorDir, bc);
return generateLodColorHorizontal(chunk, colorDir, bc);
}
return INVISIBLE;
@@ -486,7 +467,7 @@ public class LodBuilder
/**
* Generates the color for the sides of the given chunk.
*/
private Color generateLodColorHorizontalOverArea(
private Color generateLodColorHorizontal(
IChunk chunk, ColorDirection colorDir, BlockColors bc)
{
if(colorDir != ColorDirection.NORTH && colorDir != ColorDirection.SOUTH && colorDir != ColorDirection.EAST && colorDir != ColorDirection.WEST)
@@ -6,6 +6,7 @@ import com.seibel.lod.enums.ColorDirection;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.util.LodConfig;
import net.minecraft.client.renderer.BufferBuilder;
import net.minecraft.util.math.AxisAlignedBB;
@@ -14,7 +15,7 @@ import net.minecraft.util.math.AxisAlignedBB;
* Builds LODs as rectangular prisms.
*
* @author James Seibel
* @version 06-12-2021
* @version 06-13-2021
*/
public class CubicLodTemplate extends AbstractLodTemplate
{
@@ -35,7 +36,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
// Add this LOD to the BufferBuilder
// using the quality setting set by the config
LodDetail detail = LodChunk.DETAIL; //LodConfig.CLIENT.lodDetail.get();
LodDetail detail = LodConfig.CLIENT.lodDetail.get();
int halfWidth = detail.width / 2;
@@ -62,26 +63,7 @@ public class CubicLodTemplate extends AbstractLodTemplate
}
}
/*
private int[][] addColorToColorAverages(int[][] colorAverages, Color[] colorToAdd)
{
for(ColorDirection dir : ColorDirection.values())
{
// convert the colorToAdd to an int array
float[] colorCompoments = new float[4];
colorCompoments = colorToAdd[dir.value].getColorComponents(colorCompoments);
// add each color component to the array
for(int rgbIndex = 0; rgbIndex < 3; rgbIndex++)
{
// * 255 + 0.5 taken from the Color java class
colorAverages[dir.value][rgbIndex] += (int) (colorCompoments[rgbIndex] * 255 + 0.5);
}
}
return colorAverages;
}
*/
@@ -103,6 +85,45 @@ public class CubicLodTemplate extends AbstractLodTemplate
private void addBoundingBoxToBuffer(BufferBuilder buffer, AxisAlignedBB bb, Color c)
{
// top (facing up)
addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
// bottom (facing down)
addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
// south (facing -Z)
addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
// north (facing +Z)
addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
// west (facing -X)
addPosAndColor(buffer, bb.minX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.minX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.minX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.minX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
// east (facing +X)
addPosAndColor(buffer, bb.maxX, bb.maxY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.maxX, bb.maxY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.maxX, bb.minY, bb.maxZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
addPosAndColor(buffer, bb.maxX, bb.minY, bb.minZ, c.getRed(), c.getGreen(), c.getBlue(), c.getAlpha());
}
@SuppressWarnings("unused")
private void addBoundingBoxToBuffer(BufferBuilder buffer, AxisAlignedBB bb, Color[] c)
{
// top (facing up)
@@ -1,18 +0,0 @@
package com.seibel.lod.enums;
/**
* top, individual_sides
*
* @author James Seibel
* @version 05-08-2021
*/
public enum LodColorStyle
{
/** Use the color from the top of the LOD chunk
* for all sides */
TOP,
/** For each side of the LOD use the color corresponding
* to that side */
INDIVIDUAL_SIDES;
}
@@ -1,12 +1,13 @@
package com.seibel.lod.enums;
import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.objects.LodDataPoint;
/**
* single, double, quad, half, full
*
* @author James Seibel
* @version 06-12-2021
* @version 06-13-2021
*/
public enum LodDetail
{
@@ -32,13 +33,20 @@ public enum LodDetail
/** How wide each LOD is */
public final int width;
/* */
/* Start/End X/Z give the block positions
* for each individual dataPoint in a LodChunk */
public final int[] startX;
public final int[] startZ;
public final int[] endX;
public final int[] endZ;
/** This is how many pieces of data should be expected
* when creating a LodChunk with this detail level */
public final int lodChunkStringDelimiterCount;
private LodDetail(int newLengthCount)
{
@@ -81,5 +89,9 @@ public enum LodDetail
index++;
}
}
}
lodChunkStringDelimiterCount = 2 + (lengthCount * lengthCount * LodDataPoint.NUMBER_OF_DELIMITERS);
}// constructor
}
@@ -8,10 +8,12 @@ import java.io.IOException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.objects.LodChunk;
import com.seibel.lod.objects.LodDimension;
import com.seibel.lod.objects.LodRegion;
import com.seibel.lod.proxy.ClientProxy;
import com.seibel.lod.util.LodConfig;
/**
* This object handles creating LodRegions
@@ -19,7 +21,7 @@ import com.seibel.lod.proxy.ClientProxy;
* to file.
*
* @author James Seibel
* @version 6-12-2021
* @version 6-13-2021
*/
public class LodDimensionFileHandler
{
@@ -32,13 +34,16 @@ public class LodDimensionFileHandler
private File dimensionDataSaveFolder;
/** lod */
private final String FILE_NAME_PREFIX = "lod";
/** .txt */
private final String FILE_EXTENSION = ".txt";
/** This is the file version currently accepted by this
* file handler, older versions (smaller numbers) will be deleted and overwritten,
* newer versions (larger numbers) will be ignored and won't be read. */
public static final int LOD_SAVE_FILE_VERSION = 1;
public static final int LOD_SAVE_FILE_VERSION = 2;
/** This is the string written before the file version */
private static final String LOD_FILE_VERSION_PREFIX = "lod_save_file_version";
@@ -78,10 +83,8 @@ public class LodDimensionFileHandler
*/
public LodRegion loadRegionFromFile(int regionX, int regionZ)
{
// TODO
return null;
/*
String fileName = getFileNameAndPathForRegion(regionX, regionZ);
String fileName = getFileNameAndPathForRegion(regionX, regionZ, LodConfig.CLIENT.lodDetail.get());
File f = new File(fileName);
@@ -156,7 +159,7 @@ public class LodDimensionFileHandler
try
{
// convert each line into an LOD object and add it to the region
LodChunk lod = new LodChunk(s);
LodChunk lod = new LodChunk(s, LodConfig.CLIENT.lodDetail.get());
region.addLod(lod);
}
@@ -181,7 +184,6 @@ public class LodDimensionFileHandler
}
return region;
*/
}
@@ -200,8 +202,7 @@ public class LodDimensionFileHandler
*/
public void saveDirtyRegionsToFileAsync()
{
// TODO
//fileWritingThreadPool.execute(saveDirtyRegionsThread);
fileWritingThreadPool.execute(saveDirtyRegionsThread);
}
private Thread saveDirtyRegionsThread = new Thread(() ->
@@ -234,7 +235,7 @@ public class LodDimensionFileHandler
int x = region.x;
int z = region.z;
File f = new File(getFileNameAndPathForRegion(x, z));
File f = new File(getFileNameAndPathForRegion(x, z, LodConfig.CLIENT.lodDetail.get()));
try
{
@@ -320,9 +321,11 @@ public class LodDimensionFileHandler
/**
* Return the name of the file that should contain the
* region at the given x and z. <br>
* Returns null if this object isn't ready to read and write.
* Returns null if this object isn't ready to read and write. <br><br>
*
* example: "lod.FULL.0.0.txt"
*/
private String getFileNameAndPathForRegion(int regionX, int regionZ)
private String getFileNameAndPathForRegion(int regionX, int regionZ, LodDetail detail)
{
try
{
@@ -330,8 +333,8 @@ public class LodDimensionFileHandler
// ".\Super Flat\DIM-1\data"
// or
// ".\Super Flat\data"
return dimensionDataSaveFolder.getCanonicalPath() + "\\" +
FILE_NAME_PREFIX + "." + regionX + "." + regionZ + FILE_EXTENSION;
return dimensionDataSaveFolder.getCanonicalPath() + "\\" +
FILE_NAME_PREFIX + "." + detail.toString() + "." + regionX + "." + regionZ + FILE_EXTENSION;
}
catch(IOException e)
{
+175 -162
View File
@@ -2,10 +2,8 @@ package com.seibel.lod.objects;
import java.awt.Color;
import com.seibel.lod.enums.ColorDirection;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.handlers.LodDimensionFileHandler;
import com.seibel.lod.util.LodConfig;
import net.minecraft.util.math.ChunkPos;
@@ -14,13 +12,10 @@ import net.minecraft.util.math.ChunkPos;
* and color data for an LOD object.
*
* @author James Seibel
* @version 6-12-2021
* @version 6-13-2021
*/
public class LodChunk
{
/** how many different pieces of data are in one line */
private static final int DATA_DELIMITER_COUNT = 22;
/** This is what separates each piece of data in the toData method */
private static final char DATA_DELIMITER = LodDimensionFileHandler.DATA_DELIMITER;
@@ -34,7 +29,7 @@ public class LodChunk
private static final Color INVISIBLE = new Color(0,0,0,0);
public static final LodDetail DETAIL = LodDetail.QUAD;
public LodDetail detail = LodDetail.SINGLE;
/** The x coordinate of the chunk. */
@@ -60,11 +55,12 @@ public class LodChunk
x = 0;
z = 0;
dataPoints = new LodDataPoint[DETAIL.lengthCount][DETAIL.lengthCount];
detail = LodDetail.SINGLE;
dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount];
}
// TODO
/**
* Creates an LodChunk from the string
* generated by the toData method.
@@ -72,97 +68,99 @@ public class LodChunk
* @throws IllegalArgumentException if the data isn't valid to create a LodChunk
* @throws NumberFormatException if any piece of data can't be converted at any point
*/
// public LodChunk(String data) throws IllegalArgumentException, NumberFormatException
// {
// /*
// * data format:
// * x, z, height, depth, rgb color data
// *
// * example:
// * 5,8, 4, 0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255,
// */
//
// // make sure there are the correct number of entries
// // in the data string (28)
// int count = 0;
//
// for(int i = 0; i < data.length(); i++)
// if(data.charAt(i) == DATA_DELIMITER)
// count++;
//
// if(count != DATA_DELIMITER_COUNT)
// throw new IllegalArgumentException("LodChunk constructor givin an invalid string. The data given had " + count + " delimiters when it should have had " + DATA_DELIMITER_COUNT + ".");
//
//
//
// // index we will use when going through the String
// int index = 0;
// int lastIndex = 0;
//
//
//
// // x and z position
// index = data.indexOf(DATA_DELIMITER, 0);
// x = Integer.parseInt(data.substring(0,index));
//
// lastIndex = index;
// index = data.indexOf(DATA_DELIMITER, lastIndex+1);
// z = Integer.parseInt(data.substring(lastIndex+1,index));
//
// // height
// lastIndex = index;
// index = data.indexOf(DATA_DELIMITER, lastIndex+1);
// // TODO
// //height = Short.parseShort(data.substring(lastIndex+1,index));
//
// // depth
// lastIndex = index;
// index = data.indexOf(DATA_DELIMITER, lastIndex+1);
// //depth = Short.parseShort(data.substring(lastIndex+1,index));
//
//
//
// // color
// //colors = new Color[6];
// for(ColorDirection dir : ColorDirection.values())
// {
// int red = 0;
// int green = 0;
// int blue = 0;
//
// // get r,g,b
// for(int i = 0; i < 3; i++)
// {
// lastIndex = index;
// index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
//
// String raw = "";
// switch(i)
// {
// case 0:
// raw = data.substring(lastIndex+1,index);
// red = Short.parseShort(raw);
// break;
// case 1:
// raw = data.substring(lastIndex+1,index);
// green = Short.parseShort(raw);
// break;
// case 2:
// raw = data.substring(lastIndex+1,index);
// blue = Short.parseShort(raw);
// break;
// }
// }
//
// // TODO
// //colors[dir.value] = new Color(red, green, blue);
// }
//
//
// // after going through all this
// // is this LOD empty?
// empty = determineIfEmtpy();
// }
public LodChunk(String data, LodDetail newDetail) throws IllegalArgumentException, NumberFormatException
{
/*
* data format:
* x, z, dataPoint[0][0], dataPoint[0][1], ...
* x, z, height, depth, rgb color data, height, depth, rgb....
*
* example:
* 5,8, 4, 0, 255,255,255, 4, 0, 255, 255, 255, ...
*/
// make sure there are the correct number of entries
// in the data string
int count = 0;
for(int i = 0; i < data.length(); i++)
if(data.charAt(i) == DATA_DELIMITER)
count++;
if(count != detail.lodChunkStringDelimiterCount)
throw new IllegalArgumentException("LodChunk constructor givin an invalid string. The data given had " + count + " delimiters when it should have had " + detail.lodChunkStringDelimiterCount + ".");
detail = newDetail;
dataPoints = new LodDataPoint[detail.lengthCount][detail.lengthCount];
// index we will use when going through the String
int index = 0;
int lastIndex = 0;
// x and z position
index = data.indexOf(DATA_DELIMITER, 0);
this.x = Integer.parseInt(data.substring(0,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
this.z = Integer.parseInt(data.substring(lastIndex+1,index));
// LodDataPoints
for(int blockX = 0; blockX < detail.lengthCount; blockX++)
{
for(int blockZ = 0; blockZ < detail.lengthCount; blockZ++)
{
// height
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int height = Short.parseShort(data.substring(lastIndex+1,index));
// depth
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int depth = Short.parseShort(data.substring(lastIndex+1,index));
// color
int red = 0;
int green = 0;
int blue = 0;
// get r,g,b
for(int i = 0; i < 3; i++)
{
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex + 1);
String raw = "";
switch(i)
{
case 0:
raw = data.substring(lastIndex+1,index);
red = Short.parseShort(raw);
break;
case 1:
raw = data.substring(lastIndex+1,index);
green = Short.parseShort(raw);
break;
case 2:
raw = data.substring(lastIndex+1,index);
blue = Short.parseShort(raw);
break;
}
}
dataPoints[blockX][blockZ] = new LodDataPoint((short)height, (short)depth, new Color(red, green, blue));
}
}
empty = determineIfEmtpy();
}
/**
* Create a LodChunk from the given values.
@@ -218,11 +216,13 @@ public class LodChunk
if(dataPoint.height >= 0)
{
// the height is valid,
// do we have at least 1 non-invisible color?
for(ColorDirection dir : ColorDirection.values())
if(!dataPoint.colors[dir.value].equals(INVISIBLE))
// at least one direction has a non-invisible color
return false;
if (dataPoint.color == INVISIBLE)
continue;
// the color and height are valid
// this LodChunk isn't empty
return false;
}
}
}
@@ -243,16 +243,12 @@ public class LodChunk
*/
public LodDataPoint getDataPointForBlockPos(int blockX, int blockZ)
{
if (blockX < 0 || blockX > WIDTH || blockX < 0 || blockZ > WIDTH)
throw new IllegalArgumentException("The coordinates given are outside the LodChunk");
return dataPoints[blockX / DETAIL.width][blockZ / DETAIL.width];
return dataPoints[blockX / detail.width][blockZ / detail.width];
}
/** Returns the color for the given direction */
public Color getColorForBlockPos(int blockX, int blockZ, ColorDirection dir)
public Color getColorForBlockPos(int blockX, int blockZ)
{
return getDataPointForBlockPos(blockX, blockZ).colors[dir.value];
return getDataPointForBlockPos(blockX, blockZ).color;
}
public short getHeightForBlockPos(int blockX, int blockZ)
@@ -266,6 +262,23 @@ public class LodChunk
}
public Color getColor(int xIndex, int zIndex)
{
return dataPoints[xIndex][zIndex].color;
}
public short getHeight(int xIndex, int zIndex)
{
return dataPoints[xIndex][zIndex].height;
}
public short getDepth(int xIndex, int zIndex)
{
return dataPoints[xIndex][zIndex].depth;
}
/**
* @param startX
* @param startZ
@@ -304,68 +317,71 @@ public class LodChunk
/**
* Determine the color for each side of this LOD.
* Determine the color of this LOD.
*/
public Color[] getAverageColorOverArea(int startX, int startZ, int endX, int endZ, boolean debugging)
public Color getAverageColorOverArea(int startX, int startZ, int endX, int endZ, boolean debugging)
{
Color[] colors = new Color[ColorDirection.values().length];
int[] colorComponents = new int[3];
if (debugging)
{
// draw the squares as a black and white,
// like a checker board
// only return 1 color to prevent
// getting back gray
if ((startX + startZ) % 2 == 0)
return DEBUG_WHITE;
else
return DEBUG_BLACK;
}
for(int x = startX; x < endX; x++)
{
for(int z = startZ; z < endZ; z++)
{
if (!debugging)
{
// if NOT debugging, look to the config to determine
// how this LOD should be colored
switch (LodConfig.CLIENT.lodColorStyle.get())
{
case TOP:
// only add the top's color to the array
for(ColorDirection dir : ColorDirection.values())
colors[dir.value] = getColorForBlockPos(x,z, ColorDirection.TOP);
break;
case INDIVIDUAL_SIDES:
// add each direction's color to the array
for(ColorDirection dir : ColorDirection.values())
colors[dir.value] = getColorForBlockPos(x,z, dir);
break;
}
}
else
{
// if debugging draw the squares as a black and white checker board
if ((x + z) % 2 == 0)
for(ColorDirection dir : ColorDirection.values())
// have each direction be the same
// color if debugging
colors[dir.value] = DEBUG_WHITE;
else
for(ColorDirection dir : ColorDirection.values())
colors[dir.value] = DEBUG_BLACK;
}
colorComponents = addColorToColorAverages(colorComponents, getColorForBlockPos(x,z));
}
}
return colors;
int numbPoints = ((endX - startX) * (endZ - startZ));
return new Color(colorComponents[0]/numbPoints, colorComponents[1]/numbPoints, colorComponents[2]/numbPoints);
}
private int[] addColorToColorAverages(int[] colorAverages, Color colorToAdd)
{
// convert the colorToAdd to an int array
float[] colorCompoments = new float[4];
colorCompoments = colorToAdd.getColorComponents(colorCompoments);
// add each color component to the array
for(int rgbIndex = 0; rgbIndex < 3; rgbIndex++)
{
// * 255 + 0.5 taken from the Color java class
colorAverages[rgbIndex] += (int) (colorCompoments[rgbIndex] * 255 + 0.5);
}
return colorAverages;
}
/**
* Outputs all data in a csv format
* with the given delimiter.
* <br>
* Exports data in the form:
* <br>
* x, z, height, depth, rgb color data
* with the given delimiter. <br><br>
*
* <br>
* example output:
* <br>
* 5,8, 4, 0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255,
* data format: <br>
* x, z, dataPoint[0][0], dataPoint[0][1], ... <br>
* x, z, height, depth, rgb color data, height, depth, rgb.... <br><br>
*
* example: <br>
* 5,8, 4, 0, 255,255,255, 4, 0, 255, 255, 255, ...
*/
public String toData()
{
@@ -373,9 +389,9 @@ public class LodChunk
s += Integer.toString(x) + DATA_DELIMITER + Integer.toString(z) + DATA_DELIMITER;
for (LodDataPoint[] dataPointArray : dataPoints)
for(LodDataPoint dataPoint : dataPointArray)
s += dataPoint.toData();
for (int i = 0; i < dataPoints.length; i++)
for (int j = 0; j < dataPoints[i].length; j++)
s += dataPoints[i][j].toData();
return s;
}
@@ -388,9 +404,6 @@ public class LodChunk
s += "x: " + x + " z: " + z + "\t";
// TODO
//s += "(" + colors[ColorDirection.TOP.value].getRed() + ", " + colors[ColorDirection.TOP.value].getGreen() + ", " + colors[ColorDirection.TOP.value].getBlue() + ")";
return s;
}
}
@@ -2,7 +2,6 @@ package com.seibel.lod.objects;
import java.awt.Color;
import com.seibel.lod.enums.ColorDirection;
import com.seibel.lod.handlers.LodDimensionFileHandler;
/**
@@ -10,13 +9,16 @@ import com.seibel.lod.handlers.LodDimensionFileHandler;
* for a specific area in a LodChunk.
*
* @author James Seibel
* @version 6-12-2021
* @version 6-13-2021
*/
public class LodDataPoint
{
/** This is what separates each piece of data in the toData method */
private static final char DATA_DELIMITER = LodDimensionFileHandler.DATA_DELIMITER;
/** this is how many pieces of data are exported when toData is called */
public static final int NUMBER_OF_DELIMITERS = 5;
private static final Color INVISIBLE = new Color(0,0,0,0);
/** highest point */
@@ -26,29 +28,25 @@ public class LodDataPoint
public short depth;
/** The average color for the 6 cardinal directions */
public Color colors[];
public Color color;
/**
* default constructor
* Creates and empty LodDataPoint
*/
public LodDataPoint()
{
height = 0;
depth = 0;
colors = new Color[ColorDirection.values().length];
// by default have the colors invisible
for(ColorDirection dir : ColorDirection.values())
colors[dir.value] = INVISIBLE;
height = -1;
depth = -1;
color = INVISIBLE;
}
public LodDataPoint(short newHeight, short newDepth, Color[] newColors)
public LodDataPoint(short newHeight, short newDepth, Color newColor)
{
height = newHeight;
depth = newDepth;
colors = newColors;
color = newColor;
}
@@ -63,19 +61,15 @@ public class LodDataPoint
* <br>
* example output:
* <br>
* 4, 0, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255, 255,255,255,
* 4, 0, 255,255,255,
*/
public String toData()
{
String s = Short.toString(height) + DATA_DELIMITER;
s += Short.toString(depth) + DATA_DELIMITER;
for(int i = 0; i < colors.length; i++)
{
s += Integer.toString(colors[i].getRed()) + DATA_DELIMITER + Integer.toString(colors[i].getGreen()) + DATA_DELIMITER + Integer.toString(colors[i].getBlue()) + DATA_DELIMITER;
}
s += Integer.toString(color.getRed()) + DATA_DELIMITER + Integer.toString(color.getGreen()) + DATA_DELIMITER + Integer.toString(color.getBlue()) + DATA_DELIMITER;
return s;
}
@@ -10,7 +10,6 @@ import com.electronwill.nightconfig.core.file.CommentedFileConfig;
import com.electronwill.nightconfig.core.io.WritingMode;
import com.seibel.lod.ModInfo;
import com.seibel.lod.enums.FogDistance;
import com.seibel.lod.enums.LodColorStyle;
import com.seibel.lod.enums.LodDetail;
import com.seibel.lod.enums.LodTemplate;
@@ -22,7 +21,7 @@ import net.minecraftforge.fml.config.ModConfig;
/**
*
* @author James Seibel
* @version 05-31-2021
* @version 6-13-2021
*/
@Mod.EventBusSubscriber
public class LodConfig
@@ -39,8 +38,6 @@ public class LodConfig
public ForgeConfigSpec.EnumValue<LodDetail> lodDetail;
public ForgeConfigSpec.EnumValue<LodColorStyle> lodColorStyle;
/** this is multiplied by the default view distance
* to determine how far out to generate/render LODs */
public ForgeConfigSpec.IntValue lodChunkRadiusMultiplier;
@@ -87,13 +84,6 @@ public class LodConfig
+ " " + LodDetail.DOUBLE.toString() + ": render 4 LODs for each Chunk.")
.defineEnum("lodGeometryQuality", LodDetail.SINGLE);
lodColorStyle = builder
.comment("\n"
+ " How should the LODs be colored? \n"
+ " " + LodColorStyle.TOP.toString() + ": Use the color from the top of the LOD chunk for all sides. \n"
+ " " + LodColorStyle.INDIVIDUAL_SIDES.toString() + ": For each side of the LOD use the color corresponding to that side. ")
.defineEnum("lodColorStyle", LodColorStyle.TOP);
lodChunkRadiusMultiplier = builder
.comment("\n"
+ " This is multiplied by the default view distance \n"