Various change to support LodDataPoint and the DistanceGenerationMode enum

This commit is contained in:
Leonardo
2021-07-13 11:38:08 +02:00
parent cd06b42b02
commit 2c719c41d9
5 changed files with 253 additions and 162 deletions
@@ -47,5 +47,4 @@ public enum DistanceGenerationMode
* are adding the mod to a pre-existing world.
* Singlethreaded - Slow (15-50 ms, with spikes up to 200 ms) */
SERVER;
}
@@ -1,5 +1,8 @@
package com.seibel.lod.objects;
import com.seibel.lod.enums.DistanceGenerationMode;
import org.lwjgl.system.CallbackI;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.List;
@@ -37,7 +40,7 @@ public class LodQuadTree {
//data useful to render
//if children are present then lodNodeData should be a combination of the lodData of the child. This can be
//turned off by deselecting the recursive update in all update method.
private LodQuadTreeNode lodQuadTreeNode;
private LodQuadTreeNode lodNode;
/*
.____.____.
| NW | NE | |
@@ -91,11 +94,11 @@ public class LodQuadTree {
/**
* Constructor for generic level via the LodNodeData
*
* @param lodQuadTreeNode object containing all the information of this node
* @param lodNode object containing all the information of this node
*/
public LodQuadTree(LodQuadTree parent, LodQuadTreeNode lodQuadTreeNode) {
public LodQuadTree(LodQuadTree parent, LodQuadTreeNode lodNode) {
this.parent = parent;
this.lodQuadTreeNode = lodQuadTreeNode;
this.lodNode = lodNode;
this.children = new LodQuadTree[2][2];
this.nodeEmpty = true;
this.nodeFull = false;
@@ -126,18 +129,18 @@ public class LodQuadTree {
}
/**
* @param newLodQuadTreeNode data to put in the node
* @param newLodNode data to put in the node
* @param updateHigherLevel will update the color and height of higher level only if true
* @return true only if the QuadTree has been changed
*/
public boolean setNodeAtLowerLevel(LodQuadTreeNode newLodQuadTreeNode, boolean updateHigherLevel) {
public boolean setNodeAtLowerLevel(LodQuadTreeNode newLodNode, boolean updateHigherLevel) {
//check if we try to introduce a level that is higher or equal than the current one
byte targetLevel = newLodQuadTreeNode.level;
byte currentLevel = lodQuadTreeNode.level;
byte targetLevel = newLodNode.level;
byte currentLevel = lodNode.level;
if (targetLevel < currentLevel) {
int posX = newLodQuadTreeNode.posX;
int posZ = newLodQuadTreeNode.posZ;
short widthRatio = (short) (lodQuadTreeNode.width / (2 * newLodQuadTreeNode.width));
int posX = newLodNode.posX;
int posZ = newLodNode.posZ;
short widthRatio = (short) (lodNode.width / (2 * newLodNode.width));
int WE = Math.abs(Math.floorDiv(posX , widthRatio) % 2);
int NS = Math.abs(Math.floorDiv(posZ , widthRatio) % 2);
//These two if fix the negative coordinate problema
@@ -153,14 +156,16 @@ public class LodQuadTree {
setChild(NS, WE);
}
LodQuadTree child = getChild(NS, WE);
if (!newLodQuadTreeNode.real && child.isNodeReal()) {
if (lodNode.compareComplexity(newLodNode) < 0) {
//the node we want to introduce is less complex than the current node
//we don't want to override higher complexity with lower complexity
return false;
} else {
if (targetLevel == currentLevel - 1) {
child.setLodNodeData(newLodQuadTreeNode, true);
child.setLodNodeData(newLodNode, true);
return true;
} else {
return child.setNodeAtLowerLevel(newLodQuadTreeNode, updateHigherLevel);
return child.setNodeAtLowerLevel(newLodNode, updateHigherLevel);
}
}
} else {
@@ -172,23 +177,22 @@ public class LodQuadTree {
/**
* @param posX
* @param posZ
* @param level
* @param targetLevel
* @return
*/
public LodQuadTreeNode getNodeAtLevelPosition(int posX, int posZ, byte level) {
byte targetLevel = level;
byte currentLevel = lodQuadTreeNode.level;
public LodQuadTreeNode getNodeAtLevelPosition(int posX, int posZ, byte targetLevel) {
byte currentLevel = lodNode.level;
if (targetLevel == currentLevel) {
return lodQuadTreeNode;
return lodNode;
} else if (targetLevel < currentLevel) {
short widthRatio = (short) (lodQuadTreeNode.width / (2 * Math.pow(2, level)));
short widthRatio = (short) (lodNode.width / (2 * Math.pow(2, targetLevel)));
int WE = Math.abs(Math.floorDiv(posX , widthRatio) % 2);
int NS = Math.abs(Math.floorDiv(posZ , widthRatio) % 2);
if (getChild(NS, WE) == null) {
return null;
}
LodQuadTree child = getChild(NS, WE);
return child.getNodeAtLevelPosition(posX, posZ, level);
return child.getNodeAtLevelPosition(posX, posZ, targetLevel);
} else {
return null;
}
@@ -203,26 +207,26 @@ public class LodQuadTree {
/**
* setChild will put a child with given data in the given position
*
* @param newLodQuadTreeNode data to put in the child
* @param newLodNode data to put in the child
* @param NS North-South position
* @param WE West-East position
*/
public void setChild(LodQuadTreeNode newLodQuadTreeNode, int NS, int WE) {
if (newLodQuadTreeNode.level == lodQuadTreeNode.level - 1) {
children[NS][WE] = new LodQuadTree(this, lodQuadTreeNode);
public void setChild(LodQuadTreeNode newLodNode, int NS, int WE) {
if (newLodNode.level == lodNode.level - 1) {
children[NS][WE] = new LodQuadTree(this, lodNode);
}
}
/**
* setChild will put a child with given data in the given position
*
* @param newLodQuadTreeNode data to put in the child
* @param newLodNode data to put in the child
*/
public void setChild(LodQuadTreeNode newLodQuadTreeNode) {
if (newLodQuadTreeNode.level == lodQuadTreeNode.level - 1) {
int WE = newLodQuadTreeNode.posX % lodQuadTreeNode.posX;
int NS = newLodQuadTreeNode.posZ % lodQuadTreeNode.posZ;
children[NS][WE] = new LodQuadTree(this, lodQuadTreeNode);
public void setChild(LodQuadTreeNode newLodNode) {
if (newLodNode.level == lodNode.level - 1) {
int WE = newLodNode.posX % lodNode.posX;
int NS = newLodNode.posZ % lodNode.posZ;
children[NS][WE] = new LodQuadTree(this, lodNode);
}
}
@@ -233,9 +237,9 @@ public class LodQuadTree {
* @param WE West-East position
*/
public void setChild(int NS, int WE) {
int childX = lodQuadTreeNode.posX * 2 + WE;
int childZ = lodQuadTreeNode.posZ * 2 + NS;
children[NS][WE] = new LodQuadTree(this, (byte) (lodQuadTreeNode.level - 1), childX, childZ);
int childX = lodNode.posX * 2 + WE;
int childZ = lodNode.posZ * 2 + NS;
children[NS][WE] = new LodQuadTree(this, (byte) (lodNode.level - 1), childX, childZ);
}
/**
@@ -259,9 +263,9 @@ public class LodQuadTree {
}
nodeFull = isFull;
nodeEmpty = isEmpty;
lodQuadTreeNode.combineData(dataList);
if (lodQuadTreeNode.level < 9 && recursiveUpdate) {
this.parent.updateLevel(recursiveUpdate);
lodNode.combineData(dataList);
if (lodNode.level < 9 && recursiveUpdate) {
this.parent.updateLevel(true);
}
}
@@ -274,14 +278,14 @@ public class LodQuadTree {
* @param getOnlyLeaf if true it will return only leaf nodes
* @return list of nodes
*/
public List<LodQuadTreeNode> getNodeList(Set<Integer> complexityMask, boolean getOnlyDirty, boolean getOnlyLeaf) {
public List<LodQuadTreeNode> getNodeList(Set<DistanceGenerationMode> complexityMask, boolean getOnlyDirty, boolean getOnlyLeaf) {
List<LodQuadTreeNode> nodeList = new ArrayList<>();
if (isThereAnyChild()) {
//There is at least 1 child
if (!getOnlyLeaf
&& !(getOnlyDirty && !lodQuadTreeNode.dirty)
&& complexityMask.contains(lodQuadTreeNode.complexity)) {
nodeList.add(lodQuadTreeNode);
&& !(getOnlyDirty && !lodNode.isDirty())
&& complexityMask.contains(lodNode.getComplexity())) {
nodeList.add(lodNode);
}
for (int NS = 0; NS <= 1; NS++) {
for (int WE = 0; WE <= 1; WE++) {
@@ -293,9 +297,9 @@ public class LodQuadTree {
}
} else {
//There are no children
if (!(getOnlyDirty && !lodQuadTreeNode.dirty)
|| (complexityMask.contains((int) lodQuadTreeNode.complexity))){
nodeList.add(lodQuadTreeNode);
if (!(getOnlyDirty && !lodNode.isDirty())
&& (complexityMask.contains(lodNode.getComplexity()))){
nodeList.add(lodNode);
}
}
@@ -312,37 +316,30 @@ public class LodQuadTree {
* @param minDistance minimum distance from the player
* @return
*/
public List<LodQuadTreeNode> getNodeToRender(int x, int z, byte targetLevel, int maxDistance, int minDistance) {
int distance = (int) Math.sqrt(Math.pow(x - lodQuadTreeNode.centerX, 2) + Math.pow(z - lodQuadTreeNode.centerZ, 2));
public List<LodQuadTreeNode> getNodeToRender(int x, int z, byte targetLevel, Set<DistanceGenerationMode> complexityMask, int maxDistance, int minDistance) {
List<Integer> distances = new ArrayList();
distances.add(distance);
distances.add((int) Math.sqrt(Math.pow(x - lodQuadTreeNode.startX, 2) + Math.pow(z - lodQuadTreeNode.startZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodQuadTreeNode.startX, 2) + Math.pow(z - lodQuadTreeNode.endZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodQuadTreeNode.endX, 2) + Math.pow(z - lodQuadTreeNode.startZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodQuadTreeNode.endX, 2) + Math.pow(z - lodQuadTreeNode.endZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getCenterX(), 2) + Math.pow(z - lodNode.getCenterX(), 2)));
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)));
int min = distances.stream().mapToInt(Integer::intValue).min().getAsInt();
int max = distances.stream().mapToInt(Integer::intValue).max().getAsInt();
List<LodQuadTreeNode> nodeList = new ArrayList<>();
if (targetLevel > lodQuadTreeNode.level) {
return nodeList;
}
if ((min > maxDistance || max < minDistance) /*&& !isCoordinateInLevel(x,z)*/){
return nodeList;
}
if (targetLevel == lodQuadTreeNode.level || !isNodeFull()) {
if (lodQuadTreeNode.voidNode) {
nodeList.add(lodQuadTreeNode);
return nodeList;
if (!(targetLevel > lodNode.level || ((min > maxDistance || max < minDistance) /*&& !isCoordinateInLevel(x,z)*/))) {
if (targetLevel == lodNode.level || !isNodeFull()) {
if (!lodNode.isVoidNode() && complexityMask.contains(lodNode.getComplexity())) {
nodeList.add(lodNode);
}
} else {
nodeList.add(lodQuadTreeNode);
return nodeList;
}
} else {
for (int NS = 0; NS <= 1; NS++) {
for (int WE = 0; WE <= 1; WE++) {
LodQuadTree child = getChild(NS,WE);
if (child != null) {
nodeList.addAll(child.getNodeToRender(x, z, targetLevel, maxDistance, minDistance));
for (int NS = 0; NS <= 1; NS++) {
for (int WE = 0; WE <= 1; WE++) {
LodQuadTree child = getChild(NS, WE);
if (child != null) {
nodeList.addAll(child.getNodeToRender(x, z, targetLevel, complexityMask, maxDistance, minDistance));
}
}
}
}
@@ -350,76 +347,65 @@ public class LodQuadTree {
return nodeList;
}
/**
* Nodes that can be generated in the approximated version
* A level is generated only if it has child and is higher than the target level and in the distance range
* @param x
* @param z
* @param targetLevel
* @param complexityToGenerate
* @param maxDistance
* @param minDistance
* @return
*/
public List<AbstractMap.SimpleEntry<LodQuadTree, Integer>> getLevelToGenerate(int x, int z, byte targetLevel, int maxDistance, int minDistance) {
int distance = (int) Math.sqrt(Math.pow(x - lodQuadTreeNode.centerX, 2) + Math.pow(z - lodQuadTreeNode.centerZ, 2));
public List<AbstractMap.SimpleEntry<LodQuadTree, Integer>> getLevelToGenerate(int x, int z, byte targetLevel, DistanceGenerationMode complexityToGenerate, int maxDistance, int minDistance) {
List<Integer> distances = new ArrayList();
distances.add(distance);
distances.add((int) Math.sqrt(Math.pow(x - lodQuadTreeNode.startX, 2) + Math.pow(z - lodQuadTreeNode.startZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodQuadTreeNode.startX, 2) + Math.pow(z - lodQuadTreeNode.endZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodQuadTreeNode.endX, 2) + Math.pow(z - lodQuadTreeNode.startZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodQuadTreeNode.endX, 2) + Math.pow(z - lodQuadTreeNode.endZ, 2)));
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getCenterX(), 2) + Math.pow(z - lodNode.getCenterX(), 2)));
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)));
int min = distances.stream().mapToInt(Integer::intValue).min().getAsInt();
int max = distances.stream().mapToInt(Integer::intValue).max().getAsInt();
List<AbstractMap.SimpleEntry<LodQuadTree, Integer>> nodeList = new ArrayList<>();
if ( targetLevel > lodQuadTreeNode.level ) {
return nodeList;
}
if ((min > maxDistance || max < minDistance)/* && !isCoordinateInLevel(x,z)*/){
if ( targetLevel > lodNode.level || ((min > maxDistance || max < minDistance)/* && !isCoordinateInLevel(x,z)*/)) {
return nodeList;
}
if(isNodeFull()) {
//THIS LEVEL HAS CHILD SO IT'S GENERATED.
if (targetLevel != lodQuadTreeNode.level) {
if (targetLevel != lodNode.level) {
for (int NS = 0; NS <= 1; NS++) {
for (int WE = 0; WE <= 1; WE++) {
if (getChild(NS,WE) == null) {
setChild(NS,WE);
}
LodQuadTree child = getChild(NS,WE);
nodeList.addAll(child.getLevelToGenerate(x, z, targetLevel, maxDistance, minDistance));
}
}
}
} else {
nodeList.add(new AbstractMap.SimpleEntry<>(this, distance));
/*
if(isThereAnyChild()){
for (int NS = 0; NS <= 1; NS++) {
for (int WE = 0; WE <= 1; WE++) {
if (children[NS][WE] == null) {
setChild(NS,WE);
LodQuadTree child = children[NS][WE];
distance = (int) Math.sqrt(Math.pow(x - child.lodNodeData.centerX, 2) + Math.pow(z - child.lodNodeData.centerZ, 2));
nodeList.add(new AbstractMap.SimpleEntry<>(child, distance));
}
nodeList.addAll(child.getLevelToGenerate(x, z, targetLevel, complexityToGenerate, maxDistance, minDistance));
}
}
}else{
nodeList.add(new AbstractMap.SimpleEntry<>(this, distance));
if(this.lodNode.getComplexity().compareTo(complexityToGenerate) > 0) {
//we want to regenerate a level only if we ask for higher complexity
nodeList.add(new AbstractMap.SimpleEntry<>(this, min)
}
}
*/
} else {
nodeList.add(new AbstractMap.SimpleEntry<>(this, min));
}
return nodeList;
}
/**
* simple getter for lodNodeData
*
* @return lodNodeData
*/
public LodQuadTreeNode getLodNodeData() {
return lodQuadTreeNode;
return lodNode;
}
/**
@@ -429,10 +415,10 @@ public class LodQuadTree {
* @param updateHigherLevel if true it will update all the upper levels.
*/
public void setLodNodeData(LodQuadTreeNode newLodQuadTreeNode, boolean updateHigherLevel) {
if (this.lodQuadTreeNode == null) {
this.lodQuadTreeNode = newLodQuadTreeNode;
if (this.lodNode == null) {
this.lodNode = newLodQuadTreeNode;
} else {
this.lodQuadTreeNode.update(newLodQuadTreeNode);
this.lodNode.update(newLodQuadTreeNode);
}
//a recursive update is necessary to change higher level
if (parent != null && updateHigherLevel) parent.updateLevel(true);
@@ -446,21 +432,17 @@ public class LodQuadTree {
return !nodeEmpty;
}
public boolean isNodeReal() {
return lodQuadTreeNode.real;
}
public boolean isRenderable() {
return (lodQuadTreeNode != null);
return (lodNode != null);
}
public boolean isCoordinateInLevel(int x, int z){
return !(lodQuadTreeNode.startX > x || lodQuadTreeNode.startZ > z || lodQuadTreeNode.endX < x || lodQuadTreeNode.endZ < z);
return !(lodNode.getStartX() > x || lodNode.getStartZ() > z || lodNode.getEndX() < x || lodNode.getEndZ() < z);
}
public String toString(){
String s = lodQuadTreeNode.toString();
String s = lodNode.toString();
return s;
/*
if(isThereAnyChild()){
@@ -1,5 +1,6 @@
package com.seibel.lod.objects;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.handlers.LodQuadTreeDimensionFileHandler;
import com.seibel.lod.util.LodUtil;
import net.minecraft.client.Minecraft;
@@ -251,11 +252,11 @@ public class LodQuadTreeDimension {
* stored in the LOD. If an LOD already exists at the given
* coordinates it will be overwritten.
*/
public Boolean addNode(LodQuadTreeNode lodQuadTreeNode)
public Boolean addNode(LodQuadTreeNode lodNode)
{
RegionPos pos = new RegionPos(
lodQuadTreeNode.startX / 512,
lodQuadTreeNode.startZ / 512
lodNode.getStartX() / 512,
lodNode.getStartZ() / 512
);
// don't continue if the region can't be saved
@@ -272,10 +273,10 @@ public class LodQuadTreeDimension {
region = new LodQuadTree(pos.x, pos.z);
setRegion(region);
}
boolean coorectlyAdded = region.setNodeAtLowerLevel(lodQuadTreeNode, true);
boolean coorectlyAdded = region.setNodeAtLowerLevel(lodNode, true);
// don't save empty place holders to disk
if (lodQuadTreeNode.real && fileHandler != null)
if (fileHandler != null)
{
// mark the region as dirty so it will be saved to disk
int xIndex = (pos.x - centerX) + halfWidth;
@@ -310,16 +311,24 @@ public class LodQuadTreeDimension {
*/
}
/**
* return true if and only if the node at that position exist
*/
public boolean hasThisPositionBeenGenerated(int posX, int posZ, byte level)
{
return getLodFromCoordinates(posX,posZ,level).level == level
}
/**
* method to get all the nodes that have to be rendered based on the position of the player
* @return list of nodes
*/
public List<LodQuadTreeNode> getNodeToRender(int x, int z, byte level, int maxDistance, int minDistance){
public List<LodQuadTreeNode> getNodeToRender(int x, int z, byte level, Set<DistanceGenerationMode> complexityMask, int maxDistance, int minDistance){
int n = regions.length;
List<LodQuadTreeNode> listOfData = new ArrayList<>();
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
listOfData.addAll(regions[i][j].getNodeToRender(x,z,level,maxDistance,minDistance));
listOfData.addAll(regions[i][j].getNodeToRender(x,z,level,complexityMask,maxDistance,minDistance));
}
}
return listOfData;
@@ -356,7 +365,7 @@ public class LodQuadTreeDimension {
* getNodes
* @return list of quadTrees
*/
public List<LodQuadTreeNode> getNodes(boolean getOnlyReal, boolean getOnlyDirty, boolean getOnlyLeaf){
public List<LodQuadTreeNode> getNodes(Set<DistanceGenerationMode> complexityMask, boolean getOnlyDirty, boolean getOnlyLeaf){
int n = regions.length;
List<LodQuadTreeNode> listOfNodes = new ArrayList<>();
int xIndex;
@@ -368,7 +377,7 @@ public class LodQuadTreeDimension {
zIndex = (zRegion + centerZ) - halfWidth;
region = getRegion(xIndex,zIndex);
if (region != null){
listOfNodes.addAll(region.getNodeList(getOnlyReal, getOnlyDirty, getOnlyLeaf));
listOfNodes.addAll(region.getNodeList(complexityMask, getOnlyDirty, getOnlyLeaf));
}
}
}
@@ -1,6 +1,8 @@
package com.seibel.lod.objects;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.handlers.LodQuadTreeDimensionFileHandler;
import net.minecraftforge.api.distmarker.Dist;
import java.awt.*;
import java.util.*;
@@ -13,14 +15,13 @@ public class LodQuadTreeNode {
/** this is how many pieces of data are exported when toData is called */
public static final int NUMBER_OF_DELIMITERS = 9;
public static final int NUMBER_OF_DELIMITERS = 10;
private static final Color INVISIBLE = new Color(0,0,0,0);
//Complexity indicate how complex is this node. For example a node that has been generated starting
//from a real chunk have the maximum complexity. A node that is generated starting from a fake approximated chunk
//has a low complexity
public byte complexity;
//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 level;
@@ -42,7 +43,7 @@ public class LodQuadTreeNode {
//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 and levelWidth
//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;
@@ -79,20 +80,49 @@ public class LodQuadTreeNode {
endZ = startZ + width - 1;
centerX = startX + width/2;
centerZ = startZ + width/2;
lodDataPoint = new LodDataPoint()
real = false;
lodDataPoint = new LodDataPoint();
complexity = null;
dirty = true;
voidNode = 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 level level of this
* @param posX
* @param posZ
* @param lodDataPoint
* @param complexity
*/
public LodQuadTreeNode(byte level, int posX, int posZ, LodDataPoint lodDataPoint, byte complexity){
public LodQuadTreeNode(byte level, int posX, int posZ, LodDataPoint lodDataPoint, DistanceGenerationMode complexity){
this.level = level;
this.posX = posX;
this.posZ = posZ;
@@ -104,7 +134,7 @@ public class LodQuadTreeNode {
centerX = startX + width/2;
centerZ = startZ + width/2;
this.lodDataPoint = lodDataPoint;
this.real = real;
this.complexity = complexity;
dirty = true;
voidNode = false;
}
@@ -116,6 +146,9 @@ public class LodQuadTreeNode {
index = data.indexOf(DATA_DELIMITER, 0);
this.level = (byte) Integer.parseInt(data.substring(0,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);
@@ -127,11 +160,11 @@ public class LodQuadTreeNode {
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
this.height = (short) Integer.parseInt(data.substring(lastIndex+1,index));
short height = (short) Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
this.depth = (short) Integer.parseInt(data.substring(lastIndex+1,index));
short depth = (short) Integer.parseInt(data.substring(lastIndex+1,index));
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
@@ -145,14 +178,13 @@ public class LodQuadTreeNode {
lastIndex = index;
index = data.indexOf(DATA_DELIMITER, lastIndex+1);
int a = Integer.parseInt(data.substring(lastIndex+1,index));
this.color = new Color(r,g,b,a);
Color color = new Color(r,g,b,a);
lodDataPoint = new LodDataPoint(height,depth,color);
int complexity = Integer.parseInt(data.substring(lastIndex+1,index));
this.real = (val == 1);
width = (short) Math.pow(2, level);
val = Integer.parseInt(data.substring(lastIndex+1,index));
int val = Integer.parseInt(data.substring(lastIndex+1,index));
this.voidNode = (val == 1);
width = (short) Math.pow(2, level);
startX = posX * width;
startZ = posZ * width;
endX = startX + width - 1;
@@ -163,7 +195,7 @@ public class LodQuadTreeNode {
}
public void update(LodQuadTreeNode lodQuadTreeNode){
this.lodDataPoint = lodQuadTreeNode.lodDataPoint
this.lodDataPoint = lodQuadTreeNode.lodDataPoint;
this.complexity = lodQuadTreeNode.complexity;
this.voidNode = lodQuadTreeNode.voidNode;
dirty = true;
@@ -172,9 +204,6 @@ public class LodQuadTreeNode {
public LodDataPoint getLodDataPoint(){
return lodDataPoint;
}
public byte getComplexity(){
return complexity;
}
public void combineData(List<LodQuadTreeNode> dataList){
if(dataList.isEmpty()){
@@ -189,7 +218,16 @@ public class LodQuadTreeNode {
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);
complexity = (byte) dataList.stream().mapToInt(x -> x.complexity).max().getAsInt();
//the new complexity equal to the lowest complexity of the list
DistanceGenerationMode minComplexity = DistanceGenerationMode.SERVER;
dataList.forEach(x -> {
if (minComplexity.compareTo(x.complexity) < 0){
minComplexity = x.complexity;
}
});
complexity = minComplexity;
voidNode = dataList.stream().filter(x -> !x.voidNode).count() == 0;
}
dirty = true;
@@ -197,7 +235,11 @@ public class LodQuadTreeNode {
public int hashCode(){
return Objects.hash(this.complexity, this.level, this.posX, this.posZ, this.color, this.real, this.voidNode);
return Objects.hash(this.complexity, this.level, this.posX, this.posZ, this.lodDataPoint, this.voidNode);
}
public int compareComplexity(LodQuadTreeNode other){
return this.complexity.compareTo(other.complexity);
}
@@ -206,8 +248,8 @@ public class LodQuadTreeNode {
&& this.level == other.level
&& this.posX == other.posX
&& this.posZ == other.posZ
&& this.color.equals(other.color)
&& this.real == other.real
&& this.lodDataPoint.equals(other.lodDataPoint)
&& this.complexity == other.complexity
&& this.voidNode == other.voidNode);
}
@@ -216,18 +258,17 @@ public class LodQuadTreeNode {
* Outputs all data in a csv format
*/
public String toData(){
String s = Integer.toString(level) + DATA_DELIMITER
String s = ((int) level) + DATA_DELIMITER
+ complexity.toString() + DATA_DELIMITER
+ posX + DATA_DELIMITER
+ posZ + DATA_DELIMITER
+ Integer.toString(height) + DATA_DELIMITER
+ Integer.toString(depth) + DATA_DELIMITER
+ color.getRed() + DATA_DELIMITER
+ color.getGreen() + DATA_DELIMITER
+ color.getBlue() + DATA_DELIMITER
+ color.getAlpha() + DATA_DELIMITER;
int val = real ? 1 : 0;
s += val + DATA_DELIMITER;
val = voidNode ? 1 : 0;
+ ((int) lodDataPoint.height) + DATA_DELIMITER
+ ((int) lodDataPoint.depth) + DATA_DELIMITER
+ lodDataPoint.color.getRed() + DATA_DELIMITER
+ lodDataPoint.color.getGreen() + DATA_DELIMITER
+ lodDataPoint.color.getBlue() + DATA_DELIMITER
+ lodDataPoint.color.getAlpha() + DATA_DELIMITER;
int val = voidNode ? 1 : 0;
s += val + DATA_DELIMITER;
return s;
}
@@ -238,4 +279,59 @@ public class LodQuadTreeNode {
{
return this.toData();
}
// This getters should be used
public byte getLevel() {
return level;
}
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;
}
}
@@ -1,5 +1,6 @@
package com.seibel.lod.objects;
import com.seibel.lod.enums.DistanceGenerationMode;
import com.seibel.lod.util.BiomeColorsUtils;
import kaptainwutax.biomeutils.source.OverworldBiomeSource;
import kaptainwutax.mcutils.version.MCVersion;
@@ -18,9 +19,7 @@ import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.*;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
@@ -159,7 +158,13 @@ public class QuadTreeImage extends JPanel {
lodList.addAll(dim.getNodeToRender(playerX,playerZ,(byte) 9, 100000,8000));
System.out.println(lodList.size());
*/
List<LodQuadTreeNode> lodList = dim.getNodes(false,false,false);
Set<DistanceGenerationMode> complexityMask = new HashSet<>();
complexityMask.add(DistanceGenerationMode.SERVER);
complexityMask.add(DistanceGenerationMode.FEATURES);
complexityMask.add(DistanceGenerationMode.SURFACE);
complexityMask.add(DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT);
complexityMask.add(DistanceGenerationMode.BIOME_ONLY);
List<LodQuadTreeNode> lodList = dim.getNodes(complexityMask,false,false);
// lodList.addAll(lodQuadTree.getNodeToRender(playerX, playerZ, (byte) 2, 100, 0));
// lodList.addAll(lodQuadTree.getNodeToRender(playerX, playerZ, (byte) 3, 200, 100));
// lodList.addAll(lodQuadTree.getNodeToRender(playerX, playerZ, (byte) 4, 400, 200));