Refactoring, reformatting, and commenting

I removed the getters from LodQuadTreeNode since they were public variables anyway.
This commit is contained in:
James Seibel
2021-08-08 00:09:12 -05:00
parent 7f7884c130
commit 64b8cb3556
4 changed files with 385 additions and 412 deletions
@@ -181,7 +181,7 @@ public class LodNodeBufferBuilder
LodQuadTreeNode lod = lodDim.getLodFromCoordinates(new ChunkPos(chunkX, chunkZ), LodQuadTreeNode.CHUNK_LEVEL);
if (lod == null || lod.getComplexity() == DistanceGenerationMode.NONE)
if (lod == null || lod.complexity == DistanceGenerationMode.NONE)
{
// generate a new chunk if no chunk currently exists
// and we aren't waiting on any other chunks to generate
@@ -18,6 +18,7 @@
package com.seibel.lod.enums;
/**
* NONE <br>
* BIOME_ONLY <br>
* BIOME_ONLY_SIMULATE_HEIGHT <br>
* SURFACE <br>
@@ -27,13 +28,14 @@ package com.seibel.lod.enums;
* In order of fastest to slowest.
*
* @author James Seibel
* @version 6-27-2021
* @author Leonardo Amato
* @version 8-7-2021
*/
public enum DistanceGenerationMode
{
/** No generation has be used*/
/** Don't generate anything */
NONE(0),
/** Only generate the biomes and use biome
* grass/foliage color, water color, or ice color
* to generate the color.
@@ -67,17 +69,13 @@ public enum DistanceGenerationMode
* are adding the mod to a pre-existing world.
* Singlethreaded - Slow (15-50 ms, with spikes up to 200 ms) */
SERVER(5);
/** The higher the number the more complete the generation is. */
public final int complexity;
DistanceGenerationMode(int complexity) {
DistanceGenerationMode(int complexity)
{
this.complexity = complexity;
}
/*
public int compareTo(DistanceGenerationMode other){
return Integer.compare(complexity, other.complexity);
)
*/
}
@@ -347,7 +347,7 @@ public class LodQuadTree
// this detail level's node
if (!getOnlyLeaf && !(getOnlyDirty && !lodNode.isDirty())
&& complexityMask.contains(lodNode.getComplexity()))
&& complexityMask.contains(lodNode.complexity))
{
nodeList.add(lodNode);
}
@@ -370,7 +370,7 @@ public class LodQuadTree
{
// This tree has no children
if (!(getOnlyDirty && !lodNode.isDirty()) && (complexityMask.contains(lodNode.getComplexity())))
if (!(getOnlyDirty && !lodNode.isDirty()) && (complexityMask.contains(lodNode.complexity)))
{
nodeList.add(lodNode);
}
@@ -395,10 +395,10 @@ public class LodQuadTree
int z = playerPos.getZ();
List<Integer> distances = new ArrayList<>();
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getStartX(), 2) + Math.pow(z - lodNode.getStartZ(), 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getStartX(), 2) + Math.pow(z - lodNode.getEndZ(), 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getEndX(), 2) + Math.pow(z - lodNode.getStartZ(), 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getEndX(), 2) + Math.pow(z - lodNode.getEndZ(), 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.startX, 2) + Math.pow(z - lodNode.startZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.startX, 2) + Math.pow(z - lodNode.endZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.endX, 2) + Math.pow(z - lodNode.startZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.endX, 2) + Math.pow(z - lodNode.endZ, 2)));
int min = distances.stream().mapToInt(Integer::intValue).min().getAsInt();
int max = distances.stream().mapToInt(Integer::intValue).max().getAsInt();
@@ -412,7 +412,7 @@ public class LodQuadTree
{
// we have either reached the right detail level or this tree isn't full
if (!lodNode.isVoidNode() && complexityMask.contains(lodNode.getComplexity()))
if (!lodNode.isVoidNode() && complexityMask.contains(lodNode.complexity))
{
// this node isn't void and has the complexity level we are looking for
nodeList.add(lodNode);
@@ -449,10 +449,10 @@ public class LodQuadTree
int z = playerPos.getZ();
List<Integer> distances = new ArrayList<>();
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getStartX(), 2) + Math.pow(z - lodNode.getStartZ(), 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getStartX(), 2) + Math.pow(z - lodNode.getEndZ(), 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getEndX(), 2) + Math.pow(z - lodNode.getStartZ(), 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getEndX(), 2) + Math.pow(z - lodNode.getEndZ(), 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.startX, 2) + Math.pow(z - lodNode.startZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.startX, 2) + Math.pow(z - lodNode.endZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.endX, 2) + Math.pow(z - lodNode.startZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.endX, 2) + Math.pow(z - lodNode.endZ, 2)));
int min = distances.stream().mapToInt(Integer::intValue).min().getAsInt();
int max = distances.stream().mapToInt(Integer::intValue).max().getAsInt();
@@ -465,7 +465,7 @@ public class LodQuadTree
// TODO shouldn't tagetLevel be != lodNode.detailLevel?
if(!hasChildren() || targetLevel == lodNode.detailLevel)
{
if (this.lodNode.getComplexity().compareTo(complexityToGenerate) <= 0 )
if (this.lodNode.complexity.compareTo(complexityToGenerate) <= 0 )
{
nodeList.add(new AbstractMap.SimpleEntry<LodQuadTreeNode, Integer>(this.lodNode, min));
}
@@ -522,10 +522,10 @@ public class LodQuadTree
*/
public boolean isCoordinateInQuadTree(BlockPos pos)
{
return (lodNode.getStartX() * lodNode.width <= pos.getX() &&
lodNode.getStartZ() * lodNode.width <= pos.getZ() &&
lodNode.getEndX() * lodNode.width >= pos.getX() &&
lodNode.getEndZ() * lodNode.width >= pos.getZ());
return (lodNode.startX * lodNode.width <= pos.getX() &&
lodNode.startZ * lodNode.width <= pos.getZ() &&
lodNode.endX * lodNode.width >= pos.getX() &&
lodNode.endZ * lodNode.width >= pos.getZ());
}
@@ -27,12 +27,20 @@ import com.seibel.lod.handlers.LodQuadTreeDimensionFileHandler;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.gen.Heightmap;
/**
* This object contains position
* and color data for an LOD object.
*
* @author Leonardo Amato
* @author James Seibel
* @version 8-7-2021
*/
public class LodQuadTreeNode
{
/** This is what separates each piece of data in the toData method */
private static final char DATA_DELIMITER = LodQuadTreeDimensionFileHandler.DATA_DELIMITER;
private static final char DATA_DELIMITER = LodQuadTreeDimensionFileHandler.DATA_DELIMITER;
/** alpha used when drawing chunks in debug mode */
/** alpha used when drawing chunks in debug mode */
private static final int DEBUG_ALPHA = 255; // 0 - 255
@SuppressWarnings("unused")
private static final Color DEBUG_BLACK = new Color(0, 0, 0, DEBUG_ALPHA);
@@ -44,389 +52,356 @@ public class LodQuadTreeNode
/** If we ever have to use a heightmap for any reason, use this one. */
public static final Heightmap.Type DEFAULT_HEIGHTMAP = Heightmap.Type.WORLD_SURFACE_WG;
/** If this is set to true then toData will return
* the empty string */
public boolean dontSave = false;
/** this is how many pieces of data are exported when toData is called */
public static final int NUMBER_OF_DELIMITERS = 10;
//Complexity indicate how the block was built. This is important because we could use
public DistanceGenerationMode complexity;
//level height goes from 0 to 9 with 0 the deepest (block size) and 9 the highest (region size)
public final byte detailLevel;
public static final byte REGION_LEVEL = 9; //at level 9 we reach the dimension of a single region
public static final byte CHUNK_LEVEL = 4; //at level 4 we reach the dimension of a single chunk
public static final byte BLOCK_LEVEL = 0; //at level 0 we reach the dimension of a single block
//indicate the width in block of this node (goes from 1 to 512)
public final short width;
public static final short REGION_WIDTH = 512; //at level 9 we reach the dimension of a single region
public static final short CHUNK_WIDTH = 16; //at level 4 we reach the dimension of a single chunk
public static final short BLOCK_WIDTH = 1; //at level 0 we reach the dimension of a single block
//this 2 values indicate the position of the LOD in the relative Level
//this will be useful in the generation process
public final int posX;
public final int posZ;
//these 4 value indicate the corner of the LOD block
//they can be named SW, SE, NW, NE as the cardinal direction.
//the start values should always be smaller than the end values.
//All this value could be calculated from level, posx and posz
//so they could be removed and replaced with just a getter
public final int startX;
public final int startZ;
public final int endX;
public final int endZ;
//these 2 value indicate the center of the LodNode in real coordinate. This
//can be used to calculate the distance from the player
public final int centerX;
public final int centerZ;
public LodDataPoint lodDataPoint;
//void node is used
public boolean voidNode;
//if dirty is true, then this node have unsaved changes
public boolean dirty;
/**TODO There should be a check for the level. Level must be positive, i could use runtime exception or simple if*/
/**TODO There should be a good way to create node that must not be saved
* For example loading a 64 region wide dimension that is fully generated is too much memory heavy.
* There should be a way to create Node that are approximated and at region level, so you could load those
* for far region, and then when you get closer you load the actual region from the file or you generate it.
* */
/**
* Creates and empty LodDataPoint
* This LodDataPoint only contains the position data
* @param detailLevel of the node
* @param posX position x in the level
* @param posZ position z in the level
*/
public LodQuadTreeNode(ChunkPos pos)
{
this(CHUNK_LEVEL, pos.x, pos.z);
}
/**
* Creates and empty LodDataPoint
* This LodDataPoint only contains the position data
* @param detailLevel of the node
* @param posX position x in the level
* @param posZ position z in the level
*/
public LodQuadTreeNode(byte detailLevel, int posX, int posZ)
{
this.detailLevel = detailLevel;
this.posX = posX;
this.posZ = posZ;
width = (short) Math.pow(2, detailLevel);
startX = posX * width;
startZ = posZ * width;
endX = startX + width - 1;
endZ = startZ + width - 1;
centerX = startX + width/2;
centerZ = startZ + width/2;
lodDataPoint = new LodDataPoint();
complexity = DistanceGenerationMode.NONE;
dirty = true;
voidNode = true;
dontSave = true;
}
/**
* Constructor for a LodNodeData
* @param level
* @param posX
* @param posZ
* @param height
* @param depth
* @param color
* @param complexity
*/
public LodQuadTreeNode(byte level, int posX, int posZ, short height, short depth , Color color, DistanceGenerationMode complexity)
{
this(level, posX, posZ, new LodDataPoint(height,depth,color), complexity);
}
/**
* Constructor for a LodNodeData
* @param level
* @param posX
* @param posZ
* @param height
* @param depth
* @param color
* @param complexity
*/
public LodQuadTreeNode(byte level, int posX, int posZ, int height , int depth , Color color, DistanceGenerationMode complexity)
{
this(level, posX, posZ, new LodDataPoint(height,depth,color), complexity);
}
/**
* Constructor for a LodNodeData
* @param detailLevel level of this
* @param posX
* @param posZ
* @param lodDataPoint
* @param complexity
*/
public LodQuadTreeNode(byte detailLevel, int posX, int posZ, LodDataPoint lodDataPoint, DistanceGenerationMode complexity)
{
this.detailLevel = detailLevel;
this.posX = posX;
this.posZ = posZ;
width = (short) Math.pow(2, detailLevel);
startX = posX * width;
startZ = posZ * width;
endX = startX + width - 1;
endZ = startZ + width - 1;
centerX = startX + width/2;
centerZ = startZ + width/2;
this.lodDataPoint = lodDataPoint;
this.complexity = complexity;
dirty = true;
voidNode = false;
dontSave = false;
}
public LodQuadTreeNode(String data)
{
int index = 0;
int lastIndex = 0;
index = data.indexOf(DATA_DELIMITER, 0);
this.detailLevel = (byte) Integer.parseInt(data.substring(0,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
this.posX = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
this.posZ = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
this.complexity = DistanceGenerationMode.valueOf(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
short height = (short) Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
short depth = (short) Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int r = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int g = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int b = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int a = Integer.parseInt(data.substring(lastIndex+1,index));
Color color = new Color(r,g,b,a);
lodDataPoint = new LodDataPoint(height,depth,color);
int val = Integer.parseInt(data.substring(lastIndex+1,index));
this.voidNode = (val == 1);
width = (short) Math.pow(2, detailLevel);
startX = posX * width;
startZ = posZ * width;
endX = startX + width - 1;
endZ = startZ + width - 1;
centerX = startX + width/2;
centerZ = startZ + width/2;
dirty = false;
dontSave = false;
}
public void update(LodQuadTreeNode lodQuadTreeNode){
this.lodDataPoint = lodQuadTreeNode.lodDataPoint;
this.complexity = lodQuadTreeNode.complexity;
this.voidNode = lodQuadTreeNode.voidNode;
dirty = true;
dontSave = false;
}
public LodDataPoint getLodDataPoint(){
return lodDataPoint;
}
public void combineData(List<LodQuadTreeNode> dataList)
{
if(dataList.isEmpty())
{
lodDataPoint = new LodDataPoint();
}
else
{
short height = (short) dataList.stream().mapToInt(x -> (int) x.getLodDataPoint().height).min().getAsInt();
short depth = (short) dataList.stream().mapToInt(x -> (int) x.getLodDataPoint().depth).max().getAsInt();
int red = dataList.stream().mapToInt(x -> x.getLodDataPoint().color.getRed()).sum()/dataList.size();
int green = dataList.stream().mapToInt(x -> x.getLodDataPoint().color.getGreen()).sum()/dataList.size();
int blue = dataList.stream().mapToInt(x -> x.getLodDataPoint().color.getBlue()).sum()/dataList.size();
Color color = new Color(red,green,blue);
lodDataPoint = new LodDataPoint(height,depth,color);
//the new complexity equal to the lowest complexity of the list
DistanceGenerationMode minComplexity = DistanceGenerationMode.SERVER;
for(LodQuadTreeNode node: dataList)
{
if (minComplexity.compareTo(node.complexity) > 0)
{
minComplexity = node.complexity;
}
}
complexity = minComplexity;
voidNode = dataList.stream().filter(x -> !x.voidNode).count() == 0;
}
dirty = true;
dontSave = false;
}
@Override
public int hashCode(){
return Objects.hash(this.complexity, this.detailLevel, this.posX, this.posZ, this.lodDataPoint, this.voidNode);
}
public int compareComplexity(LodQuadTreeNode other){
return this.complexity.compareTo(other.complexity);
}
public boolean equals(LodQuadTreeNode other){
return (this.complexity == other.complexity
&& this.detailLevel == other.detailLevel
&& this.posX == other.posX
&& this.posZ == other.posZ
&& this.lodDataPoint.equals(other.lodDataPoint)
&& this.complexity == other.complexity
&& this.voidNode == other.voidNode);
}
/**
* Outputs all data in a csv format
*/
public String toData()
{
if (dontSave)
return "";
String s = Integer.toString(detailLevel) + DATA_DELIMITER
+ Integer.toString(posX) + DATA_DELIMITER
+ Integer.toString(posZ) + DATA_DELIMITER
+ complexity.toString() + DATA_DELIMITER
+ Integer.toString((lodDataPoint.height)) + DATA_DELIMITER
+ Integer.toString((lodDataPoint.depth)) + DATA_DELIMITER
+ Integer.toString(lodDataPoint.color.getRed()) + DATA_DELIMITER
+ Integer.toString(lodDataPoint.color.getGreen()) + DATA_DELIMITER
+ Integer.toString(lodDataPoint.color.getBlue()) + DATA_DELIMITER
+ Integer.toString(lodDataPoint.color.getAlpha()) + DATA_DELIMITER;
int val = voidNode ? 1 : 0;
s += Integer.toString(val) + DATA_DELIMITER;
return s;
}
@Override
/** this is how many pieces of data are exported when toData is called */
public static final int NUMBER_OF_DELIMITERS = 10;
//Complexity indicate how the block was built. This is important because we could use
public DistanceGenerationMode complexity;
/** Indicates how complicated this node is. <br>
* Goes from 0 to 9, 0 being the deepest (block size) and 9 being the highest (region size) */
public final byte detailLevel;
/** 512 blocks wide */
public static final byte REGION_LEVEL = 9;
/** 16 blocks wide */
public static final byte CHUNK_LEVEL = 4;
/** 1 block wide */
public static final byte BLOCK_LEVEL = 0;
/** Indicates the width in blocks of this node. <br>
* Goes from 1 to 512 */
public final short width;
/** detail level 9 */
public static final short REGION_WIDTH = 512;
/** detail level 4 */
public static final short CHUNK_WIDTH = 16;
/** detail level 0 */
public static final short BLOCK_WIDTH = 1;
//this 2 values indicate the position of the LOD in the relative Level
//this will be useful in the generation process
public final int posX;
public final int posZ;
//these 4 value indicate the corner of the LOD block
//they can be named SW, SE, NW, NE as the cardinal direction.
//the start values should always be smaller than the end values.
//All this value could be calculated from level, posx and posz
//so they could be removed and replaced with just a getter
public final int startX;
public final int startZ;
public final int endX;
public final int endZ;
//these 2 value indicate the center of the LodNode in real coordinate. This
//can be used to calculate the distance from the player
public final int centerX;
public final int centerZ;
public LodDataPoint lodDataPoint;
//void node is used
public boolean voidNode;
//if dirty is true, then this node have unsaved changes
public boolean dirty;
/**TODO There should be a check for the level. Level must be positive, i could use runtime exception or simple if*/
/**TODO There should be a good way to create node that must not be saved
* For example loading a 64 region wide dimension that is fully generated is too much memory heavy.
* There should be a way to create Node that are approximated and at region level, so you could load those
* for far region, and then when you get closer you load the actual region from the file or you generate it.
* */
/**
* Creates and empty LodDataPoint
* This LodDataPoint only contains the position data
* @param detailLevel of the node
* @param posX position x in the level
* @param posZ position z in the level
*/
public LodQuadTreeNode(ChunkPos pos)
{
this(CHUNK_LEVEL, pos.x, pos.z);
}
/**
* Creates and empty LodDataPoint
* This LodDataPoint only contains the position data
* @param detailLevel of the node
* @param posX position x in the level
* @param posZ position z in the level
*/
public LodQuadTreeNode(byte detailLevel, int posX, int posZ)
{
this.detailLevel = detailLevel;
this.posX = posX;
this.posZ = posZ;
width = (short) Math.pow(2, detailLevel);
startX = posX * width;
startZ = posZ * width;
endX = startX + width - 1;
endZ = startZ + width - 1;
centerX = startX + width/2;
centerZ = startZ + width/2;
lodDataPoint = new LodDataPoint();
complexity = DistanceGenerationMode.NONE;
dirty = true;
voidNode = true;
dontSave = true;
}
/**
* Constructor for a LodNodeData
* @param level
* @param posX
* @param posZ
* @param height
* @param depth
* @param color
* @param complexity
*/
public LodQuadTreeNode(byte level, int posX, int posZ, short height, short depth , Color color, DistanceGenerationMode complexity)
{
this(level, posX, posZ, new LodDataPoint(height,depth,color), complexity);
}
/**
* Constructor for a LodNodeData
* @param level
* @param posX
* @param posZ
* @param height
* @param depth
* @param color
* @param complexity
*/
public LodQuadTreeNode(byte level, int posX, int posZ, int height, int depth, Color color, DistanceGenerationMode complexity)
{
this(level, posX, posZ, new LodDataPoint(height,depth,color), complexity);
}
/**
* Constructor for a LodNodeData
* @param detailLevel level of this
* @param posX
* @param posZ
* @param lodDataPoint
* @param complexity
*/
public LodQuadTreeNode(byte detailLevel, int posX, int posZ, LodDataPoint lodDataPoint, DistanceGenerationMode complexity)
{
this.detailLevel = detailLevel;
this.posX = posX;
this.posZ = posZ;
width = (short) Math.pow(2, detailLevel);
startX = posX * width;
startZ = posZ * width;
endX = startX + width - 1;
endZ = startZ + width - 1;
centerX = startX + width/2;
centerZ = startZ + width/2;
this.lodDataPoint = lodDataPoint;
this.complexity = complexity;
dirty = true;
voidNode = false;
dontSave = false;
}
public LodQuadTreeNode(String data)
{
int index = 0;
int lastIndex = 0;
index = data.indexOf(DATA_DELIMITER, 0);
this.detailLevel = (byte) Integer.parseInt(data.substring(0,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
this.posX = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
this.posZ = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
this.complexity = DistanceGenerationMode.valueOf(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
short height = (short) Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
short depth = (short) Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int r = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int g = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int b = Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int a = Integer.parseInt(data.substring(lastIndex+1,index));
Color color = new Color(r,g,b,a);
lodDataPoint = new LodDataPoint(height,depth,color);
int val = Integer.parseInt(data.substring(lastIndex+1,index));
this.voidNode = (val == 1);
width = (short) Math.pow(2, detailLevel);
startX = posX * width;
startZ = posZ * width;
endX = startX + width - 1;
endZ = startZ + width - 1;
centerX = startX + width/2;
centerZ = startZ + width/2;
dirty = false;
dontSave = false;
}
public void update(LodQuadTreeNode lodQuadTreeNode)
{
this.lodDataPoint = lodQuadTreeNode.lodDataPoint;
this.complexity = lodQuadTreeNode.complexity;
this.voidNode = lodQuadTreeNode.voidNode;
dirty = true;
dontSave = false;
}
public LodDataPoint getLodDataPoint()
{
return lodDataPoint;
}
public void combineData(List<LodQuadTreeNode> dataList)
{
if(dataList.isEmpty())
{
lodDataPoint = new LodDataPoint();
}
else
{
short height = (short) dataList.stream().mapToInt(x -> (int) x.getLodDataPoint().height).min().getAsInt();
short depth = (short) dataList.stream().mapToInt(x -> (int) x.getLodDataPoint().depth).max().getAsInt();
int red = dataList.stream().mapToInt(x -> x.getLodDataPoint().color.getRed()).sum()/dataList.size();
int green = dataList.stream().mapToInt(x -> x.getLodDataPoint().color.getGreen()).sum()/dataList.size();
int blue = dataList.stream().mapToInt(x -> x.getLodDataPoint().color.getBlue()).sum()/dataList.size();
Color color = new Color(red,green,blue);
lodDataPoint = new LodDataPoint(height,depth,color);
//the new complexity equal to the lowest complexity of the list
DistanceGenerationMode minComplexity = DistanceGenerationMode.SERVER;
for(LodQuadTreeNode node: dataList)
{
if (minComplexity.compareTo(node.complexity) > 0)
{
minComplexity = node.complexity;
}
}
complexity = minComplexity;
voidNode = dataList.stream().filter(x -> !x.voidNode).count() == 0;
}
dirty = true;
dontSave = false;
}
@Override
public int hashCode()
{
return Objects.hash(this.complexity, this.detailLevel, this.posX, this.posZ, this.lodDataPoint, this.voidNode);
}
public int compareComplexity(LodQuadTreeNode other)
{
return this.complexity.compareTo(other.complexity);
}
public boolean equals(LodQuadTreeNode other)
{
return (this.complexity == other.complexity
&& this.detailLevel == other.detailLevel
&& this.posX == other.posX
&& this.posZ == other.posZ
&& this.lodDataPoint.equals(other.lodDataPoint)
&& this.complexity == other.complexity
&& this.voidNode == other.voidNode);
}
public boolean isVoidNode()
{
return voidNode;
}
public boolean isDirty()
{
return dirty;
}
/**
* Outputs all data in a csv format
*/
public String toData()
{
if (dontSave)
return "";
String s = Integer.toString(detailLevel) + DATA_DELIMITER
+ Integer.toString(posX) + DATA_DELIMITER
+ Integer.toString(posZ) + DATA_DELIMITER
+ complexity.toString() + DATA_DELIMITER
+ Integer.toString((lodDataPoint.height)) + DATA_DELIMITER
+ Integer.toString((lodDataPoint.depth)) + DATA_DELIMITER
+ Integer.toString(lodDataPoint.color.getRed()) + DATA_DELIMITER
+ Integer.toString(lodDataPoint.color.getGreen()) + DATA_DELIMITER
+ Integer.toString(lodDataPoint.color.getBlue()) + DATA_DELIMITER
+ Integer.toString(lodDataPoint.color.getAlpha()) + DATA_DELIMITER
+ Integer.toString(voidNode ? 1 : 0) + DATA_DELIMITER;
return s;
}
@Override
public String toString()
{
return this.toData();
}
// These getters should be used
public byte getDetailLevel() {
return detailLevel;
}
public DistanceGenerationMode getComplexity() {
return complexity;
}
public short getWidth() {
return width;
}
public int getPosX() {
return posX;
}
public int getPosZ() {
return posZ;
}
public int getStartX() {
return startX;
}
public int getStartZ() {
return startZ;
}
public int getEndX() {
return endX;
}
public int getEndZ() {
return endZ;
}
public int getCenterX() {
return centerX;
}
public int getCenterZ() {
return centerZ;
}
public boolean isVoidNode() {
return voidNode;
}
public boolean isDirty() {
return dirty;
}
{
return this.toData();
}
}