Add variably detailed LodChunks
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user