diff --git a/src/main/java/com/seibel/lod/builders/LodNodeBufferBuilder.java b/src/main/java/com/seibel/lod/builders/LodNodeBufferBuilder.java
index 93c19c4af..106aaba75 100644
--- a/src/main/java/com/seibel/lod/builders/LodNodeBufferBuilder.java
+++ b/src/main/java/com/seibel/lod/builders/LodNodeBufferBuilder.java
@@ -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
diff --git a/src/main/java/com/seibel/lod/enums/DistanceGenerationMode.java b/src/main/java/com/seibel/lod/enums/DistanceGenerationMode.java
index c06253254..d7968af09 100644
--- a/src/main/java/com/seibel/lod/enums/DistanceGenerationMode.java
+++ b/src/main/java/com/seibel/lod/enums/DistanceGenerationMode.java
@@ -18,6 +18,7 @@
package com.seibel.lod.enums;
/**
+ * NONE
* BIOME_ONLY
* BIOME_ONLY_SIMULATE_HEIGHT
* SURFACE
@@ -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);
- )
- */
}
diff --git a/src/main/java/com/seibel/lod/objects/LodQuadTree.java b/src/main/java/com/seibel/lod/objects/LodQuadTree.java
index 15050d904..7d83ca71e 100644
--- a/src/main/java/com/seibel/lod/objects/LodQuadTree.java
+++ b/src/main/java/com/seibel/lod/objects/LodQuadTree.java
@@ -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 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 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(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());
}
diff --git a/src/main/java/com/seibel/lod/objects/LodQuadTreeNode.java b/src/main/java/com/seibel/lod/objects/LodQuadTreeNode.java
index 637869ea4..6d69a895b 100644
--- a/src/main/java/com/seibel/lod/objects/LodQuadTreeNode.java
+++ b/src/main/java/com/seibel/lod/objects/LodQuadTreeNode.java
@@ -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 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.
+ * 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.
+ * 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 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();
+ }
+
}