Merge branch '1.16.5' of gitlab.com:jeseibel/minecraft-lod-mod into 1.16.5
This commit is contained in:
@@ -17,11 +17,7 @@
|
||||
*/
|
||||
package com.seibel.lod.handlers;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
@@ -115,100 +111,105 @@ public class LodQuadTreeDimensionFileHandler
|
||||
int regionZ = regionPos.z;
|
||||
|
||||
String fileName = getFileNameAndPathForRegion(regionX, regionZ);
|
||||
|
||||
File f = new File(fileName);
|
||||
|
||||
if (!f.exists())
|
||||
{
|
||||
// there wasn't a file, don't
|
||||
// return anything
|
||||
return null;
|
||||
}
|
||||
|
||||
List<LodQuadTreeNode> dataList = new ArrayList<>();
|
||||
try
|
||||
{
|
||||
BufferedReader br = new BufferedReader(new FileReader(f));
|
||||
String s = br.readLine();
|
||||
int fileVersion = -1;
|
||||
|
||||
if(s != null && !s.isEmpty())
|
||||
{
|
||||
// try to get the file version
|
||||
try
|
||||
{
|
||||
fileVersion = Integer.parseInt(s.substring(s.indexOf(' ')).trim());
|
||||
}
|
||||
catch(NumberFormatException | StringIndexOutOfBoundsException e)
|
||||
{
|
||||
// this file doesn't have a version
|
||||
// keep the version as -1
|
||||
fileVersion = -1;
|
||||
}
|
||||
|
||||
// check if this file can be read by this file handler
|
||||
if(fileVersion < LOD_SAVE_FILE_VERSION)
|
||||
{
|
||||
// the file we are reading is an older version,
|
||||
// close the reader and delete the file.
|
||||
br.close();
|
||||
f.delete();
|
||||
ClientProxy.LOGGER.info("Outdated LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion +
|
||||
", version requested: " + LOD_SAVE_FILE_VERSION +
|
||||
" File was been deleted.");
|
||||
|
||||
return null;
|
||||
}
|
||||
else if(fileVersion > LOD_SAVE_FILE_VERSION)
|
||||
{
|
||||
// the file we are reading is a newer version,
|
||||
// close the reader and ignore the file, we don't
|
||||
// want to accidently delete anything the user may want.
|
||||
br.close();
|
||||
ClientProxy.LOGGER.info("Newer LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion +
|
||||
", version requested: " + LOD_SAVE_FILE_VERSION +
|
||||
" this region will not be written to in order to protect the newer file.");
|
||||
|
||||
return null;
|
||||
}
|
||||
if(FILE_EXTENSION == ".bin"){
|
||||
try {
|
||||
ObjectInputStream is = new ObjectInputStream(new FileInputStream(fileName));
|
||||
List<LodQuadTreeNode> dataList = (List<LodQuadTreeNode>) is.readObject();
|
||||
//LodQuadTree region = (LodQuadTree) is.readObject();
|
||||
is.close();
|
||||
return new LodQuadTree(dataList, regionX, regionZ);
|
||||
//return region;
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
else
|
||||
{
|
||||
// there is no data in this file
|
||||
br.close();
|
||||
return new LodQuadTree(new ArrayList<>(), regionX, regionZ);
|
||||
//return null;
|
||||
}
|
||||
|
||||
if(FILE_EXTENSION == ".txt") {
|
||||
File f = new File(fileName);
|
||||
|
||||
if (!f.exists()) {
|
||||
// there wasn't a file, don't
|
||||
// return anything
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
// this file is a readable version, begin reading the file
|
||||
s = br.readLine();
|
||||
|
||||
while(s != null && !s.isEmpty())
|
||||
{
|
||||
try
|
||||
{
|
||||
dataList.add(new LodQuadTreeNode(s));
|
||||
|
||||
List<LodQuadTreeNode> dataList = new ArrayList<>();
|
||||
try {
|
||||
BufferedReader br = new BufferedReader(new FileReader(f));
|
||||
String s = br.readLine();
|
||||
int fileVersion = -1;
|
||||
|
||||
if (s != null && !s.isEmpty()) {
|
||||
// try to get the file version
|
||||
try {
|
||||
fileVersion = Integer.parseInt(s.substring(s.indexOf(' ')).trim());
|
||||
} catch (NumberFormatException | StringIndexOutOfBoundsException e) {
|
||||
// this file doesn't have a version
|
||||
// keep the version as -1
|
||||
fileVersion = -1;
|
||||
}
|
||||
|
||||
// check if this file can be read by this file handler
|
||||
if (fileVersion < LOD_SAVE_FILE_VERSION) {
|
||||
// the file we are reading is an older version,
|
||||
// close the reader and delete the file.
|
||||
br.close();
|
||||
f.delete();
|
||||
ClientProxy.LOGGER.info("Outdated LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion +
|
||||
", version requested: " + LOD_SAVE_FILE_VERSION +
|
||||
" File was been deleted.");
|
||||
|
||||
return null;
|
||||
} else if (fileVersion > LOD_SAVE_FILE_VERSION) {
|
||||
// the file we are reading is a newer version,
|
||||
// close the reader and ignore the file, we don't
|
||||
// want to accidently delete anything the user may want.
|
||||
br.close();
|
||||
ClientProxy.LOGGER.info("Newer LOD region file for region: (" + regionX + "," + regionZ + ") version: " + fileVersion +
|
||||
", version requested: " + LOD_SAVE_FILE_VERSION +
|
||||
" this region will not be written to in order to protect the newer file.");
|
||||
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
// there is no data in this file
|
||||
br.close();
|
||||
return null;
|
||||
}
|
||||
catch(IllegalArgumentException e)
|
||||
{
|
||||
// we were unable to create this chunk
|
||||
// for whatever reason.
|
||||
// skip to the next chunk
|
||||
ClientProxy.LOGGER.warn(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// this file is a readable version, begin reading the file
|
||||
s = br.readLine();
|
||||
|
||||
while (s != null && !s.isEmpty()) {
|
||||
try {
|
||||
dataList.add(new LodQuadTreeNode(s));
|
||||
} catch (IllegalArgumentException e) {
|
||||
// we were unable to create this chunk
|
||||
// for whatever reason.
|
||||
// skip to the next chunk
|
||||
ClientProxy.LOGGER.warn(e.getMessage());
|
||||
}
|
||||
|
||||
s = br.readLine();
|
||||
}
|
||||
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
// the buffered reader encountered a
|
||||
// problem reading the file
|
||||
return null;
|
||||
}
|
||||
|
||||
br.close();
|
||||
return new LodQuadTree(dataList, regionX, regionZ);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// the buffered reader encountered a
|
||||
// problem reading the file
|
||||
return null;
|
||||
}
|
||||
return new LodQuadTree(dataList, regionX, regionZ);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -258,85 +259,86 @@ public class LodQuadTreeDimensionFileHandler
|
||||
// convert to region coordinates
|
||||
int x = region.getLodNodeData().posX;
|
||||
int z = region.getLodNodeData().posZ;
|
||||
|
||||
|
||||
|
||||
|
||||
File oldFile = new File(getFileNameAndPathForRegion(x, z));
|
||||
|
||||
try
|
||||
{
|
||||
// make sure the file and folder exists
|
||||
if (!oldFile.exists())
|
||||
{
|
||||
// the file doesn't exist,
|
||||
// create it and the folder if need be
|
||||
if(!oldFile.getParentFile().exists())
|
||||
oldFile.getParentFile().mkdirs();
|
||||
oldFile.createNewFile();
|
||||
if(FILE_EXTENSION == ".bin"){
|
||||
try {
|
||||
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(getFileNameAndPathForRegion(x, z)));
|
||||
os.writeObject(region.getNodeListWithMask(LodQuadTreeDimension.FULL_COMPLEXITY_MASK, false, true));
|
||||
//os.writeObject(region);
|
||||
os.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
else
|
||||
{
|
||||
// the file exists, make sure it
|
||||
// is the correct version.
|
||||
// (to make sure we don't overwrite a newer
|
||||
// version file if it exists)
|
||||
|
||||
BufferedReader br = new BufferedReader(new FileReader(oldFile));
|
||||
String s = br.readLine();
|
||||
int fileVersion = LOD_SAVE_FILE_VERSION;
|
||||
|
||||
if(s != null && !s.isEmpty())
|
||||
{
|
||||
// try to get the file version
|
||||
try
|
||||
{
|
||||
fileVersion = Integer.parseInt(s.substring(s.indexOf(' ')).trim());
|
||||
}
|
||||
catch(NumberFormatException | StringIndexOutOfBoundsException e)
|
||||
{
|
||||
// this file doesn't have a correctly formated version
|
||||
// just overwrite the file
|
||||
}
|
||||
}
|
||||
br.close();
|
||||
|
||||
// check if this file can be written to by the file handler
|
||||
if(fileVersion <= LOD_SAVE_FILE_VERSION)
|
||||
{
|
||||
// we are good to continue and overwrite the old file
|
||||
}
|
||||
else //if(fileVersion > LOD_SAVE_FILE_VERSION)
|
||||
{
|
||||
// the file we are reading is a newer version,
|
||||
// don't write anything, we don't want to accidently
|
||||
// delete anything the user may want.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// the old file is good, now create a new save file
|
||||
File newFile = new File(getFileNameAndPathForRegion(x, z) + TMP_FILE_EXTENSION);
|
||||
|
||||
FileWriter fw = new FileWriter(newFile);
|
||||
|
||||
// add the version of this file
|
||||
fw.write(LOD_FILE_VERSION_PREFIX + " " + LOD_SAVE_FILE_VERSION + "\n");
|
||||
|
||||
// add each LodChunk to the file
|
||||
List<LodQuadTreeNode> nodesToSave = Collections.unmodifiableList(region.getNodeListWithMask(LodQuadTreeDimension.FULL_COMPLEXITY_MASK, false, true));
|
||||
for (LodQuadTreeNode lodQuadTreeNode : nodesToSave)
|
||||
{
|
||||
fw.write(lodQuadTreeNode.toData() + "\n");
|
||||
lodQuadTreeNode.dirty = false;
|
||||
}
|
||||
fw.close();
|
||||
|
||||
// overwrite the old file with the new one
|
||||
Files.move(newFile.toPath(), oldFile.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
ClientProxy.LOGGER.error("LOD file write error: ");
|
||||
e.printStackTrace();
|
||||
if(FILE_EXTENSION == ".txt") {
|
||||
try {
|
||||
// make sure the file and folder exists
|
||||
if (!oldFile.exists()) {
|
||||
// the file doesn't exist,
|
||||
// create it and the folder if need be
|
||||
if (!oldFile.getParentFile().exists())
|
||||
oldFile.getParentFile().mkdirs();
|
||||
oldFile.createNewFile();
|
||||
} else {
|
||||
// the file exists, make sure it
|
||||
// is the correct version.
|
||||
// (to make sure we don't overwrite a newer
|
||||
// version file if it exists)
|
||||
|
||||
BufferedReader br = new BufferedReader(new FileReader(oldFile));
|
||||
String s = br.readLine();
|
||||
int fileVersion = LOD_SAVE_FILE_VERSION;
|
||||
|
||||
if (s != null && !s.isEmpty()) {
|
||||
// try to get the file version
|
||||
try {
|
||||
fileVersion = Integer.parseInt(s.substring(s.indexOf(' ')).trim());
|
||||
} catch (NumberFormatException | StringIndexOutOfBoundsException e) {
|
||||
// this file doesn't have a correctly formated version
|
||||
// just overwrite the file
|
||||
}
|
||||
}
|
||||
br.close();
|
||||
|
||||
// check if this file can be written to by the file handler
|
||||
if (fileVersion <= LOD_SAVE_FILE_VERSION) {
|
||||
// we are good to continue and overwrite the old file
|
||||
} else //if(fileVersion > LOD_SAVE_FILE_VERSION)
|
||||
{
|
||||
// the file we are reading is a newer version,
|
||||
// don't write anything, we don't want to accidently
|
||||
// delete anything the user may want.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// the old file is good, now create a new save file
|
||||
File newFile = new File(getFileNameAndPathForRegion(x, z) + TMP_FILE_EXTENSION);
|
||||
|
||||
FileWriter fw = new FileWriter(newFile);
|
||||
|
||||
// add the version of this file
|
||||
fw.write(LOD_FILE_VERSION_PREFIX + " " + LOD_SAVE_FILE_VERSION + "\n");
|
||||
|
||||
// add each LodChunk to the file
|
||||
List<LodQuadTreeNode> nodesToSave = Collections.unmodifiableList(region.getNodeListWithMask(LodQuadTreeDimension.FULL_COMPLEXITY_MASK, false, true));
|
||||
for (LodQuadTreeNode lodQuadTreeNode : nodesToSave) {
|
||||
fw.write(lodQuadTreeNode.toData() + "\n");
|
||||
lodQuadTreeNode.dirty = false;
|
||||
}
|
||||
fw.close();
|
||||
|
||||
// overwrite the old file with the new one
|
||||
Files.move(newFile.toPath(), oldFile.toPath(), StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING);
|
||||
} catch (Exception e) {
|
||||
ClientProxy.LOGGER.error("LOD file write error: ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
*/
|
||||
package com.seibel.lod.objects;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.*;
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
import com.seibel.lod.handlers.LodQuadTreeDimensionFileHandler;
|
||||
@@ -30,7 +31,7 @@ import com.seibel.lod.util.LodUtil;
|
||||
* @author James Seibel
|
||||
* @version 8-8-2021
|
||||
*/
|
||||
public class LodDataPoint
|
||||
public class LodDataPoint implements Serializable
|
||||
{
|
||||
/** This is what separates each piece of data in the toData method */
|
||||
private static final char DATA_DELIMITER = LodQuadTreeDimensionFileHandler.DATA_DELIMITER;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package com.seibel.lod.objects;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -32,16 +33,16 @@ import net.minecraft.util.math.ChunkPos;
|
||||
* This object contains all data useful to render LodBlock in a region (32x32 chunk to 512x512 block)
|
||||
* for every node it contains the border of said node, its size, its block position in the world,
|
||||
* color, height and depth.
|
||||
*
|
||||
*
|
||||
* @author Leonardo Amato
|
||||
* @author James Seibel
|
||||
* @version 8-7-2021
|
||||
*/
|
||||
public class LodQuadTree
|
||||
public class LodQuadTree implements Serializable
|
||||
{
|
||||
// note:
|
||||
// The term node correspond to a LodQuadTree object
|
||||
|
||||
|
||||
/*
|
||||
Example on how a LodQuadTreeRegion would be rendered (the number corresponds to the level of the LodNodeData)
|
||||
.___.___._______._______________.
|
||||
@@ -62,16 +63,16 @@ public class LodQuadTree
|
||||
| | |
|
||||
|_______________|_______________|
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/** If true SetNodesAtLowerLevel will update the color and height of all higher level nodes */
|
||||
public static boolean UPDATE_HIGHER_LEVEL = true;
|
||||
|
||||
|
||||
//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 lodNode;
|
||||
|
||||
|
||||
/*
|
||||
.____.____.
|
||||
| NW | NE | |
|
||||
@@ -85,26 +86,26 @@ public class LodQuadTree
|
||||
West - negative x
|
||||
east - positive x
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/** treeFull is true if and only if all child are not null */
|
||||
private boolean treeFull;
|
||||
private boolean treeEmpty;
|
||||
|
||||
|
||||
/**
|
||||
* The four child are based on the four diagonal cardinal directions.
|
||||
* The first index is for North and South and the second index is for East and West. <br>
|
||||
* Children should always be null for level 0.
|
||||
*/
|
||||
private final LodQuadTree[][] children;
|
||||
|
||||
|
||||
//parent should always be null for level 9, and always not null for other levels.
|
||||
private final LodQuadTree parent;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for level 0 without LodNodeData (region level constructor)
|
||||
*
|
||||
@@ -115,7 +116,7 @@ public class LodQuadTree
|
||||
{
|
||||
this(null, new LodQuadTreeNode(LodUtil.REGION_DETAIL_LEVEL, regionPos.x, regionPos.z));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for generic world without LOD data
|
||||
*
|
||||
@@ -127,7 +128,7 @@ public class LodQuadTree
|
||||
{
|
||||
this(parent, new LodQuadTreeNode(level, regionPos.x, regionPos.z));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor using a dataList
|
||||
*
|
||||
@@ -140,7 +141,7 @@ public class LodQuadTree
|
||||
this(null, new LodQuadTreeNode(LodUtil.REGION_DETAIL_LEVEL, regionX, regionZ));
|
||||
setNodesAtLowerLevel(dataList);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor for a generic LodQuadTree using a LodNodeData
|
||||
*
|
||||
@@ -154,8 +155,8 @@ public class LodQuadTree
|
||||
treeEmpty = true;
|
||||
treeFull = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param dataList list of data to put in the node
|
||||
*/
|
||||
@@ -166,7 +167,7 @@ public class LodQuadTree
|
||||
this.setNodeAtLowerLevel(lodQuadTreeNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param newLowerLodNode data to put in the node
|
||||
* @return true only if the QuadTree has been changed
|
||||
@@ -175,24 +176,24 @@ public class LodQuadTree
|
||||
{
|
||||
byte targetLevel = newLowerLodNode.detailLevel;
|
||||
byte currentLevel = lodNode.detailLevel;
|
||||
|
||||
|
||||
if (targetLevel >= currentLevel)
|
||||
{
|
||||
// we can't add a node that has a equal or higher
|
||||
// detail level than this region
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
short widthRatio = (short) (lodNode.width / (2 * newLowerLodNode.width));
|
||||
int WE = Math.abs(Math.floorDiv(newLowerLodNode.posX , widthRatio) % 2);
|
||||
int NS = Math.abs(Math.floorDiv(newLowerLodNode.posZ , widthRatio) % 2);
|
||||
|
||||
|
||||
if (getChild(NS, WE) == null)
|
||||
{
|
||||
// if this child doesn't exist, create an empty one
|
||||
setChild(NS, WE);
|
||||
}
|
||||
|
||||
|
||||
LodQuadTree child = getChild(NS, WE);
|
||||
if (lodNode.compareComplexity(newLowerLodNode) > 0)
|
||||
{
|
||||
@@ -214,9 +215,9 @@ public class LodQuadTree
|
||||
return child.setNodeAtLowerLevel(newLowerLodNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the LodQuadTreeNode at the given chunkPos.
|
||||
* Returns null if no such LodQuadTreeNode exists.
|
||||
@@ -313,7 +314,7 @@ public class LodQuadTree
|
||||
children[NS][WE] = new LodQuadTree(this, lodNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Put an empty child in the given position.
|
||||
*
|
||||
@@ -325,7 +326,7 @@ public class LodQuadTree
|
||||
// TODO is this correctly converting to a regionPos?
|
||||
int childRegionX = lodNode.posX * 2 + WE;
|
||||
int childRegionZ = lodNode.posZ * 2 + NS;
|
||||
|
||||
|
||||
children[NS][WE] = new LodQuadTree(this, (byte) (lodNode.detailLevel - 1), new RegionPos(childRegionX, childRegionZ));
|
||||
}
|
||||
|
||||
@@ -367,7 +368,7 @@ public class LodQuadTree
|
||||
{
|
||||
boolean isFull = true;
|
||||
boolean isEmpty = true;
|
||||
|
||||
|
||||
// determine if this region is empty or full
|
||||
List<LodQuadTreeNode> dataList = new ArrayList<>();
|
||||
for (int NS = 0; NS <= 1; NS++)
|
||||
@@ -385,20 +386,20 @@ public class LodQuadTree
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
treeFull = isFull;
|
||||
treeEmpty = isEmpty;
|
||||
|
||||
|
||||
// update this regions
|
||||
lodNode.combineData(dataList);
|
||||
|
||||
|
||||
// update sub regions if requested
|
||||
if (lodNode.detailLevel < LodUtil.REGION_DETAIL_LEVEL && recursiveUpdate)
|
||||
{
|
||||
this.parent.updateRegion(recursiveUpdate);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns nodes that match the given mask.
|
||||
*
|
||||
@@ -407,29 +408,29 @@ public class LodQuadTree
|
||||
* @param getOnlyLeaf if true it will return only leaf nodes
|
||||
* @return list of nodes
|
||||
*/
|
||||
public List<LodQuadTreeNode> getNodeListWithMask(Set<DistanceGenerationMode> complexityMask, boolean getOnlyDirty,
|
||||
public List<LodQuadTreeNode> getNodeListWithMask(Set<DistanceGenerationMode> complexityMask, boolean getOnlyDirty,
|
||||
boolean getOnlyLeaf)
|
||||
{
|
||||
List<LodQuadTreeNode> nodeList = new ArrayList<>();
|
||||
|
||||
|
||||
if (hasChildren())
|
||||
{
|
||||
//There is at least 1 child
|
||||
|
||||
|
||||
// this detail level's node
|
||||
if (!getOnlyLeaf && !(getOnlyDirty && !lodNode.isDirty())
|
||||
&& complexityMask.contains(lodNode.complexity))
|
||||
&& complexityMask.contains(lodNode.complexity))
|
||||
{
|
||||
nodeList.add(lodNode);
|
||||
}
|
||||
|
||||
|
||||
// search the children for valid nodes
|
||||
for (int NS = 0; NS <= 1; NS++)
|
||||
{
|
||||
for (int WE = 0; WE <= 1; WE++)
|
||||
{
|
||||
LodQuadTree child = children[NS][WE];
|
||||
|
||||
|
||||
if (child != null)
|
||||
{
|
||||
nodeList.addAll(child.getNodeListWithMask(complexityMask, getOnlyDirty, getOnlyLeaf));
|
||||
@@ -440,16 +441,16 @@ public class LodQuadTree
|
||||
else
|
||||
{
|
||||
// This tree has no children
|
||||
|
||||
|
||||
if (!(getOnlyDirty && !lodNode.isDirty()) && (complexityMask.contains(lodNode.complexity)))
|
||||
{
|
||||
nodeList.add(lodNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method will return all the nodes that can be rendered
|
||||
*
|
||||
@@ -459,31 +460,31 @@ public class LodQuadTree
|
||||
* @param minDistance minimum distance from the player
|
||||
* @return
|
||||
*/
|
||||
public List<LodQuadTreeNode> getNodeToRender(BlockPos playerPos, int targetLevel,
|
||||
public List<LodQuadTreeNode> getNodeToRender(BlockPos playerPos, int targetLevel,
|
||||
Set<DistanceGenerationMode> complexityMask, int maxDistance, int minDistance)
|
||||
{
|
||||
int x = playerPos.getX();
|
||||
int z = playerPos.getZ();
|
||||
|
||||
|
||||
List<Integer> distances = new ArrayList<>();
|
||||
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getStart().getX(), 2) + Math.pow(z - lodNode.getStart().getZ(), 2)));
|
||||
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getStart().getX(), 2) + Math.pow(z - lodNode.getEnd().getZ(), 2)));
|
||||
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getEnd().getX(), 2) + Math.pow(z - lodNode.getStart().getZ(), 2)));
|
||||
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getEnd().getX(), 2) + Math.pow(z - lodNode.getEnd().getZ(), 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 <= lodNode.detailLevel && ((min <= maxDistance && max >= minDistance)))
|
||||
{
|
||||
// TODO why is !isNodeFull() here? Becouse if a node is not full then at least one child is missing.
|
||||
// if one child is missing then there would be a hole if you try to render all the other child
|
||||
if (targetLevel == lodNode.detailLevel || !isNodeFull())
|
||||
{
|
||||
// we have either reached the right detail level or this tree isn't full
|
||||
|
||||
// we have either reached the right detail level or this tree isn't full
|
||||
|
||||
if (!lodNode.isVoidNode() && complexityMask.contains(lodNode.complexity))
|
||||
{
|
||||
// this node isn't void and has the complexity level we are looking for
|
||||
@@ -508,29 +509,29 @@ public class LodQuadTree
|
||||
}
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns nodes that should be generated. <br>
|
||||
* A node is generated only if it has child, is higher than the target level, and in the distance range.
|
||||
*/
|
||||
public List<AbstractMap.SimpleEntry<LodQuadTreeNode, Integer>> getNodesToGenerate(BlockPos playerPos, byte targetLevel,
|
||||
public List<AbstractMap.SimpleEntry<LodQuadTreeNode, Integer>> getNodesToGenerate(BlockPos playerPos, byte targetLevel,
|
||||
DistanceGenerationMode complexityToGenerate, int maxDistance, int minDistance)
|
||||
{
|
||||
int x = playerPos.getX();
|
||||
int z = playerPos.getZ();
|
||||
|
||||
|
||||
List<Integer> distances = new ArrayList<>();
|
||||
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getStart().getX(), 2) + Math.pow(z - lodNode.getStart().getZ(), 2)));
|
||||
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getStart().getX(), 2) + Math.pow(z - lodNode.getEnd().getZ(), 2)));
|
||||
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getEnd().getX(), 2) + Math.pow(z - lodNode.getStart().getZ(), 2)));
|
||||
distances.add((int) Math.sqrt(Math.pow(x - lodNode.getEnd().getX(), 2) + Math.pow(z - lodNode.getEnd().getZ(), 2)));
|
||||
|
||||
|
||||
int min = distances.stream().mapToInt(Integer::intValue).min().getAsInt();
|
||||
int max = distances.stream().mapToInt(Integer::intValue).max().getAsInt();
|
||||
List<AbstractMap.SimpleEntry<LodQuadTreeNode, Integer>> nodeList = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO what is the purpose of isCoordianteInLevel?
|
||||
if (targetLevel <= lodNode.detailLevel && ((min <= maxDistance && max >= minDistance) || isCoordinateInQuadTree(playerPos)))
|
||||
{
|
||||
@@ -545,7 +546,7 @@ public class LodQuadTree
|
||||
else
|
||||
{
|
||||
// check if there are nodes further down that need generation
|
||||
|
||||
|
||||
for (int NS = 0; NS <= 1; NS++)
|
||||
{
|
||||
for (int WE = 0; WE <= 1; WE++)
|
||||
@@ -554,18 +555,18 @@ public class LodQuadTree
|
||||
{
|
||||
setChild(NS, WE);
|
||||
}
|
||||
|
||||
|
||||
nodeList.addAll(getChild(NS, WE).getNodesToGenerate(playerPos, targetLevel, complexityToGenerate, maxDistance, minDistance));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nodeList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* setter for lodNodeData, to maintain a correct relationship between worlds
|
||||
* setter for lodNodeData, to maintain a correct relationship between worlds
|
||||
* this method forces an update on all parent nodes.
|
||||
*
|
||||
* @param newLodQuadTreeNode data to set
|
||||
@@ -580,14 +581,14 @@ public class LodQuadTree
|
||||
{
|
||||
this.lodNode.updateData(newLodQuadTreeNode);
|
||||
}
|
||||
|
||||
|
||||
//a recursive update is necessary to change the higher levels
|
||||
if (parent != null && UPDATE_HIGHER_LEVEL)
|
||||
if (parent != null && UPDATE_HIGHER_LEVEL)
|
||||
{
|
||||
parent.updateRegion(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns if the given BlockPos is within the boundary of
|
||||
* this LodQuadTree.
|
||||
@@ -599,50 +600,50 @@ public class LodQuadTree
|
||||
lodNode.getEnd().getX() * lodNode.width >= pos.getX() &&
|
||||
lodNode.getEnd().getZ() * lodNode.width >= pos.getZ());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// simple getters //
|
||||
//================//
|
||||
|
||||
|
||||
public LodQuadTree getChild(int NS, int WE)
|
||||
{
|
||||
return children[NS][WE];
|
||||
}
|
||||
|
||||
|
||||
public LodQuadTreeNode getLodNodeData()
|
||||
{
|
||||
return lodNode;
|
||||
}
|
||||
|
||||
|
||||
public boolean isNodeFull()
|
||||
{
|
||||
return treeFull;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasChildren()
|
||||
{
|
||||
return !treeEmpty;
|
||||
}
|
||||
|
||||
|
||||
public boolean isRenderable()
|
||||
{
|
||||
return (lodNode != null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
String s = lodNode.toString();
|
||||
|
||||
s += treeFull ? "Full and " : "";
|
||||
s += treeEmpty ? "Empty " : "";
|
||||
|
||||
|
||||
s += treeFull ? "Full and " : "";
|
||||
s += treeEmpty ? "Empty " : "";
|
||||
|
||||
if (lodNode != null)
|
||||
s += "detail: " + lodNode.detailLevel;
|
||||
|
||||
s += "detail: " + lodNode.detailLevel;
|
||||
|
||||
/*
|
||||
if(hasChildren())
|
||||
{
|
||||
@@ -657,8 +658,8 @@ public class LodQuadTree
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
*/
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@
|
||||
package com.seibel.lod.objects;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -35,7 +36,7 @@ import net.minecraft.world.gen.Heightmap;
|
||||
* @author James Seibel
|
||||
* @version 8-8-2021
|
||||
*/
|
||||
public class LodQuadTreeNode
|
||||
public class LodQuadTreeNode implements Serializable
|
||||
{
|
||||
/** This is what separates each piece of data in the toData method */
|
||||
private static final char DATA_DELIMITER = LodQuadTreeDimensionFileHandler.DATA_DELIMITER;
|
||||
|
||||
Reference in New Issue
Block a user