diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/FullDataDownSampler.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/FullDataDownSampler.java index c99e77597..3b333bf4a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/FullDataDownSampler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/FullDataDownSampler.java @@ -113,7 +113,7 @@ public class FullDataDownSampler // The source occupies only 1 datapoint in the target // FIXME: TEMP method for down-sampling: take only the corner column int sourceSectionPerTargetData = 1 << (detailDiff - CompleteFullDataSource.SECTION_SIZE_OFFSET); - if (srcPos.sectionX % sourceSectionPerTargetData != 0 || srcPos.sectionZ % sourceSectionPerTargetData != 0) + if (srcPos.getX() % sourceSectionPerTargetData != 0 || srcPos.getZ() % sourceSectionPerTargetData != 0) { return; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/CompleteFullDataSource.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/CompleteFullDataSource.java index dbf5b573c..1c97cc97b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/CompleteFullDataSource.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/CompleteFullDataSource.java @@ -332,8 +332,8 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu DhLodPos baseOffset = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel()); DhSectionPos dataOffset = chunkDataView.getSectionPos().convertNewToDetailLevel(this.getDataDetailLevel()); - int offsetX = dataOffset.sectionX - baseOffset.x; - int offsetZ = dataOffset.sectionZ - baseOffset.z; + int offsetX = dataOffset.getX() - baseOffset.x; + int offsetZ = dataOffset.getZ() - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < WIDTH && offsetZ >= 0 && offsetZ < WIDTH); this.isEmpty = false; @@ -361,13 +361,13 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu // the testPosition is outside the writePosition return false; } - else if (posToTest.sectionDetailLevel > posToWrite.sectionDetailLevel) + else if (posToTest.getDetailLevel() > posToWrite.getDetailLevel()) { // the testPosition is larger (aka is less detailed) than the writePosition, // more detailed sections shouldn't be updated by lower detail sections return false; } - else if (posToWrite.sectionDetailLevel - posToTest.sectionDetailLevel <= SECTION_SIZE_OFFSET) + else if (posToWrite.getDetailLevel() - posToTest.getDetailLevel() <= SECTION_SIZE_OFFSET) { // if the difference in detail levels is very large, the posToWrite // may be skipped, due to how we sample large detail levels by only @@ -380,9 +380,9 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu { // the difference in detail levels is very large, // check if the posToWrite is in a corner of posToTest - byte sectPerData = (byte) BitShiftUtil.powerOfTwo(posToWrite.sectionDetailLevel - posToTest.sectionDetailLevel - SECTION_SIZE_OFFSET); + byte sectPerData = (byte) BitShiftUtil.powerOfTwo(posToWrite.getDetailLevel() - posToTest.getDetailLevel() - SECTION_SIZE_OFFSET); LodUtil.assertTrue(sectPerData != 0); - return posToTest.sectionX % sectPerData == 0 && posToTest.sectionZ % sectPerData == 0; + return posToTest.getX() % sectPerData == 0 && posToTest.getZ() % sectPerData == 0; } } @@ -395,7 +395,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu @Override public DhSectionPos getSectionPos() { return this.sectionPos; } @Override - public byte getDataDetailLevel() { return (byte) (this.sectionPos.sectionDetailLevel - SECTION_SIZE_OFFSET); } + public byte getDataDetailLevel() { return (byte) (this.sectionPos.getDetailLevel() - SECTION_SIZE_OFFSET); } @Override public byte getBinaryDataFormatVersion() { return DATA_FORMAT_VERSION; } @@ -419,14 +419,14 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu public void updateFromLowerCompleteSource(CompleteFullDataSource subData) { LodUtil.assertTrue(this.sectionPos.overlapsExactly(subData.sectionPos)); - LodUtil.assertTrue(subData.sectionPos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); + LodUtil.assertTrue(subData.sectionPos.getDetailLevel() < this.sectionPos.getDetailLevel()); if (!firstDataPosCanAffectSecond(this.sectionPos, subData.sectionPos)) { return; } DhSectionPos lowerSectPos = subData.sectionPos; - byte detailDiff = (byte) (this.sectionPos.sectionDetailLevel - subData.sectionPos.sectionDetailLevel); + byte detailDiff = (byte) (this.sectionPos.getDetailLevel() - subData.sectionPos.getDetailLevel()); byte targetDataDetail = this.getDataDetailLevel(); DhLodPos minDataPos = this.sectionPos.getMinCornerLodPos(targetDataDetail); if (detailDiff <= SECTION_SIZE_OFFSET) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/HighDetailIncompleteFullDataSource.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/HighDetailIncompleteFullDataSource.java index 5d0e76eca..3c8e7c44f 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/HighDetailIncompleteFullDataSource.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/HighDetailIncompleteFullDataSource.java @@ -96,11 +96,11 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo public static HighDetailIncompleteFullDataSource createEmpty(DhSectionPos pos) { return new HighDetailIncompleteFullDataSource(pos); } private HighDetailIncompleteFullDataSource(DhSectionPos sectionPos) { - LodUtil.assertTrue(sectionPos.sectionDetailLevel > SPARSE_UNIT_DETAIL); - LodUtil.assertTrue(sectionPos.sectionDetailLevel <= MAX_SECTION_DETAIL); + LodUtil.assertTrue(sectionPos.getDetailLevel() > SPARSE_UNIT_DETAIL); + LodUtil.assertTrue(sectionPos.getDetailLevel() <= MAX_SECTION_DETAIL); this.sectionPos = sectionPos; - this.sectionCount = BitShiftUtil.powerOfTwo(sectionPos.sectionDetailLevel - SPARSE_UNIT_DETAIL); + this.sectionCount = BitShiftUtil.powerOfTwo(sectionPos.getDetailLevel() - SPARSE_UNIT_DETAIL); this.dataPointsPerSection = SECTION_SIZE / this.sectionCount; this.sparseData = new FullDataArrayAccessor[this.sectionCount * this.sectionCount]; @@ -110,11 +110,11 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo protected HighDetailIncompleteFullDataSource(DhSectionPos sectionPos, FullDataPointIdMap mapping, FullDataArrayAccessor[] data) { - LodUtil.assertTrue(sectionPos.sectionDetailLevel > SPARSE_UNIT_DETAIL); - LodUtil.assertTrue(sectionPos.sectionDetailLevel <= MAX_SECTION_DETAIL); + LodUtil.assertTrue(sectionPos.getDetailLevel() > SPARSE_UNIT_DETAIL); + LodUtil.assertTrue(sectionPos.getDetailLevel() <= MAX_SECTION_DETAIL); this.sectionPos = sectionPos; - this.sectionCount = 1 << (byte) (sectionPos.sectionDetailLevel - SPARSE_UNIT_DETAIL); + this.sectionCount = 1 << (byte) (sectionPos.getDetailLevel() - SPARSE_UNIT_DETAIL); this.dataPointsPerSection = SECTION_SIZE / this.sectionCount; LodUtil.assertTrue(this.sectionCount * this.sectionCount == data.length); @@ -144,8 +144,8 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo @Override public FullDataSourceSummaryData readSourceSummaryInfo(FullDataMetaFile dataFile, DhDataInputStream inputStream, IDhLevel level) throws IOException { - LodUtil.assertTrue(dataFile.pos.sectionDetailLevel > SPARSE_UNIT_DETAIL); - LodUtil.assertTrue(dataFile.pos.sectionDetailLevel <= MAX_SECTION_DETAIL); + LodUtil.assertTrue(dataFile.pos.getDetailLevel() > SPARSE_UNIT_DETAIL); + LodUtil.assertTrue(dataFile.pos.getDetailLevel() <= MAX_SECTION_DETAIL); int dataDetail = inputStream.readShort(); if (dataDetail != dataFile.baseMetaData.dataLevel) @@ -255,7 +255,7 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo { // calculate the number of chunks and dataPoints based on the sparseDetail and sectionSize // TODO these values should be constant, should we still be calculating them like this? - int chunks = BitShiftUtil.powerOfTwo(dataFile.pos.sectionDetailLevel - SPARSE_UNIT_DETAIL); + int chunks = BitShiftUtil.powerOfTwo(dataFile.pos.getDetailLevel() - SPARSE_UNIT_DETAIL); int dataPointsPerChunk = SECTION_SIZE / chunks; @@ -421,7 +421,7 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo @Override public DhSectionPos getSectionPos() { return this.sectionPos; } @Override - public byte getDataDetailLevel() { return (byte) (this.sectionPos.sectionDetailLevel - SECTION_SIZE_OFFSET); } + public byte getDataDetailLevel() { return (byte) (this.sectionPos.getDetailLevel() - SECTION_SIZE_OFFSET); } @Override public byte getBinaryDataFormatVersion() { return DATA_FORMAT_VERSION; } @@ -488,7 +488,7 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo public void sampleFrom(IFullDataSource fullDataSource) { DhSectionPos pos = fullDataSource.getSectionPos(); - LodUtil.assertTrue(pos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); + LodUtil.assertTrue(pos.getDetailLevel() < this.sectionPos.getDetailLevel()); LodUtil.assertTrue(pos.overlapsExactly(this.sectionPos)); if (fullDataSource.isEmpty()) { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/LowDetailIncompleteFullDataSource.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/LowDetailIncompleteFullDataSource.java index 9a43898ba..5b3d5a545 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/LowDetailIncompleteFullDataSource.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/LowDetailIncompleteFullDataSource.java @@ -84,7 +84,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp private LowDetailIncompleteFullDataSource(DhSectionPos sectionPos) { super(new FullDataPointIdMap(sectionPos), new long[WIDTH * WIDTH][0], WIDTH); - LodUtil.assertTrue(sectionPos.sectionDetailLevel > HighDetailIncompleteFullDataSource.MAX_SECTION_DETAIL); + LodUtil.assertTrue(sectionPos.getDetailLevel() > HighDetailIncompleteFullDataSource.MAX_SECTION_DETAIL); this.sectionPos = sectionPos; this.isColumnNotEmpty = new BitSet(WIDTH * WIDTH); @@ -295,7 +295,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp @Override public DhSectionPos getSectionPos() { return this.sectionPos; } @Override - public byte getDataDetailLevel() { return (byte) (this.sectionPos.sectionDetailLevel - SECTION_SIZE_OFFSET); } + public byte getDataDetailLevel() { return (byte) (this.sectionPos.getDetailLevel() - SECTION_SIZE_OFFSET); } @Override public byte getBinaryDataFormatVersion() { return DATA_FORMAT_VERSION; } @@ -331,8 +331,8 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp DhLodPos baseOffset = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel()); DhSectionPos dataOffset = data.getSectionPos().convertNewToDetailLevel(this.getDataDetailLevel()); - int offsetX = dataOffset.sectionX - baseOffset.x; - int offsetZ = dataOffset.sectionZ - baseOffset.z; + int offsetX = dataOffset.getX() - baseOffset.x; + int offsetZ = dataOffset.getZ() - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < WIDTH && offsetZ >= 0 && offsetZ < WIDTH); this.isEmpty = false; @@ -353,7 +353,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp public void sampleFrom(IFullDataSource fullDataSource) { DhSectionPos pos = fullDataSource.getSectionPos(); - LodUtil.assertTrue(pos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); + LodUtil.assertTrue(pos.getDetailLevel() < this.sectionPos.getDetailLevel()); LodUtil.assertTrue(pos.overlapsExactly(this.sectionPos)); if (fullDataSource.isEmpty()) @@ -389,7 +389,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp this.isEmpty = false; - if (this.getDataDetailLevel() > this.sectionPos.sectionDetailLevel) + if (this.getDataDetailLevel() > this.sectionPos.getDetailLevel()) { DhLodPos dataLodPos = pos.getMinCornerLodPos(this.getDataDetailLevel()); @@ -445,7 +445,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp this.isEmpty = false; this.downsampleFrom(completeSource); - if (this.getDataDetailLevel() > this.sectionPos.sectionDetailLevel) // TODO what does this mean? + if (this.getDataDetailLevel() > this.sectionPos.getDetailLevel()) // TODO what does this mean? { DhLodPos thisLodPos = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel()); DhLodPos dataLodPos = pos.getMinCornerLodPos(this.getDataDetailLevel()); @@ -488,7 +488,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp this.downsampleFrom(spottySource); - if (this.getDataDetailLevel() > this.sectionPos.sectionDetailLevel) + if (this.getDataDetailLevel() > this.sectionPos.getDetailLevel()) { DhLodPos thisLodPos = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel()); DhLodPos dataLodPos = pos.getMinCornerLodPos(this.getDataDetailLevel()); @@ -574,12 +574,12 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp { if (!posToWrite.overlapsExactly(posToTest)) return false; - if (posToTest.sectionDetailLevel > posToWrite.sectionDetailLevel) + if (posToTest.getDetailLevel() > posToWrite.getDetailLevel()) return false; - if (posToWrite.sectionDetailLevel - posToTest.sectionDetailLevel <= SECTION_SIZE_OFFSET) + if (posToWrite.getDetailLevel() - posToTest.getDetailLevel() <= SECTION_SIZE_OFFSET) return true; - byte sectPerData = (byte) (1 << (posToWrite.sectionDetailLevel - posToTest.sectionDetailLevel - SECTION_SIZE_OFFSET)); - return posToTest.sectionX % sectPerData == 0 && posToTest.sectionZ % sectPerData == 0; + byte sectPerData = (byte) (1 << (posToWrite.getDetailLevel() - posToTest.getDetailLevel() - SECTION_SIZE_OFFSET)); + return posToTest.getX() % sectPerData == 0 && posToTest.getZ() % sectPerData == 0; } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/interfaces/IFullDataSource.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/interfaces/IFullDataSource.java index 622c67d04..4eea2d091 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/interfaces/IFullDataSource.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/sources/interfaces/IFullDataSource.java @@ -103,7 +103,7 @@ public interface IFullDataSource while (posList.size() > 0) { DhSectionPos pos = posList.remove(); - if (pos.sectionDetailLevel > highestGeneratorDetailLevel) + if (pos.getDetailLevel() > highestGeneratorDetailLevel) { pos.forEachChild((childPos) -> { posList.push(childPos); }); } @@ -127,20 +127,20 @@ public interface IFullDataSource int sourceRelWidth = this.getWidthInDataPoints(); - if (quadrantPos.sectionDetailLevel < highestGeneratorDetailLevel) + if (quadrantPos.getDetailLevel() < highestGeneratorDetailLevel) { throw new IllegalArgumentException("detail level lower than world generator can accept."); } - else if (quadrantPos.sectionDetailLevel == highestGeneratorDetailLevel) + else if (quadrantPos.getDetailLevel() == highestGeneratorDetailLevel) { // we are at the highest detail level the world generator can accept, // we either need to generate this whole section, or not at all // TODO combine duplicate code - byte childDetailLevel = (byte) (quadrantPos.sectionDetailLevel); + byte childDetailLevel = (byte) (quadrantPos.getDetailLevel()); - int quadrantDetailLevelDiff = this.getSectionPos().sectionDetailLevel - childDetailLevel; + int quadrantDetailLevelDiff = this.getSectionPos().getDetailLevel() - childDetailLevel; int widthInSecPos = BitShiftUtil.powerOfTwo(quadrantDetailLevelDiff); int relWidthForSecPos = sourceRelWidth / widthInSecPos; @@ -149,8 +149,8 @@ public interface IFullDataSource - int minRelX = inputPos.sectionX - minSecPos.sectionX; - int minRelZ = inputPos.sectionZ - minSecPos.sectionZ; + int minRelX = inputPos.getX() - minSecPos.getX(); + int minRelZ = inputPos.getZ() - minSecPos.getZ(); int maxRelX = minRelX + 1; int maxRelZ = minRelZ + 1; @@ -187,11 +187,11 @@ public interface IFullDataSource // TODO comment // TODO combine duplicate code - byte childDetailLevel = (byte) (quadrantPos.sectionDetailLevel - 1); + byte childDetailLevel = (byte) (quadrantPos.getDetailLevel() - 1); for (int i = 0; i < 4; i++) { - int quadrantDetailLevelDiff = this.getSectionPos().sectionDetailLevel - childDetailLevel; + int quadrantDetailLevelDiff = this.getSectionPos().getDetailLevel() - childDetailLevel; int widthInSecPos = BitShiftUtil.powerOfTwo(quadrantDetailLevelDiff); int relWidthForSecPos = sourceRelWidth / widthInSecPos; @@ -200,8 +200,8 @@ public interface IFullDataSource - int minRelX = inputPos.sectionX - minSecPos.sectionX; - int minRelZ = inputPos.sectionZ - minSecPos.sectionZ; + int minRelX = inputPos.getX() - minSecPos.getX(); + int minRelZ = inputPos.getZ() - minSecPos.getZ(); int maxRelX = minRelX + 1; int maxRelZ = minRelZ + 1; diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/ColumnRenderSource.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/ColumnRenderSource.java index 9b42652d9..ece6027b7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/ColumnRenderSource.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/render/ColumnRenderSource.java @@ -109,7 +109,7 @@ public class ColumnRenderSource */ public ColumnRenderSource(DhSectionPos sectionPos, ColumnRenderLoader.ParsedColumnData parsedColumnData, IDhLevel level) throws IOException { - if (sectionPos.sectionDetailLevel - SECTION_SIZE_OFFSET != parsedColumnData.detailLevel) + if (sectionPos.getDetailLevel() - SECTION_SIZE_OFFSET != parsedColumnData.detailLevel) { throw new IOException("Invalid data: detail level does not match"); } @@ -360,7 +360,7 @@ public class ColumnRenderSource } this.fillDebugFlag(blockOffsetX, blockOffsetZ, LodUtil.CHUNK_WIDTH, LodUtil.CHUNK_WIDTH, ColumnRenderSource.DebugSourceFlag.DIRECT); } - else if (chunkDataView.detailLevel < this.getDataDetail() && this.getDataDetail() <= chunkDataView.getSectionPos().sectionDetailLevel) + else if (chunkDataView.detailLevel < this.getDataDetail() && this.getDataDetail() <= chunkDataView.getSectionPos().getDetailLevel()) { this.markNotEmpty(); // multiple chunk data points converting to 1 column data point @@ -390,14 +390,14 @@ public class ColumnRenderSource } this.fillDebugFlag(relStartX, relStartZ, columnsInChunk, columnsInChunk, ColumnRenderSource.DebugSourceFlag.DIRECT); } - else if (chunkDataView.getSectionPos().sectionDetailLevel < this.getDataDetail()) + else if (chunkDataView.getSectionPos().getDetailLevel() < this.getDataDetail()) { // The entire chunk is being converted to a single column data point, possibly. DhLodPos dataCornerPos = chunkDataView.getSectionPos().getMinCornerLodPos(chunkDataView.detailLevel); DhLodPos sourceCornerPos = renderSourcePos.getMinCornerLodPos(this.getDataDetail()); DhLodPos sourceStartingChangePos = dataCornerPos.convertToDetailLevel(this.getDataDetail()); - int chunksPerColumn = sourceStartingChangePos.getWidthAtDetail(chunkDataView.getSectionPos().sectionDetailLevel); - if (chunkDataView.getSectionPos().sectionX % chunksPerColumn != 0 || chunkDataView.getSectionPos().sectionZ % chunksPerColumn != 0) + int chunksPerColumn = sourceStartingChangePos.getWidthAtDetail(chunkDataView.getSectionPos().getDetailLevel()); + if (chunkDataView.getSectionPos().getX() % chunksPerColumn != 0 || chunkDataView.getSectionPos().getZ() % chunksPerColumn != 0) { return false; // not a multiple of the column size, so no change } @@ -443,7 +443,7 @@ public class ColumnRenderSource public DhSectionPos getSectionPos() { return this.sectionPos; } - public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetailLevel - SECTION_SIZE_OFFSET); } + public byte getDataDetail() { return (byte) (this.sectionPos.getDetailLevel() - SECTION_SIZE_OFFSET); } /** @return how many data points wide this {@link ColumnRenderSource} is. */ public int getWidthInDataPoints() { return BitShiftUtil.powerOfTwo(this.getDetailOffset()); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataFileHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataFileHandler.java index 8462c8c53..9fa0af4c9 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataFileHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataFileHandler.java @@ -88,11 +88,11 @@ public class FullDataFileHandler implements IFullDataSourceProvider MetaFileScanUtil.IAddUnloadedFileFunc addUnloadedFileFunc = (pos, file) -> { this.unloadedFileBySectionPos.put(pos, file); - this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.sectionDetailLevel)); + this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.getDetailLevel())); }; MetaFileScanUtil.IAddLoadedMetaFileFunc addLoadedMetaFileFunc = (pos, loadedMetaFile) -> { - this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.sectionDetailLevel)); + this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.getDetailLevel())); this.metaFileBySectionPos.put(pos, (FullDataMetaFile) loadedMetaFile); }; @@ -119,7 +119,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider @Override public CompletableFuture readAsync(DhSectionPos pos) { - this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.sectionDetailLevel)); + this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.getDetailLevel())); FullDataMetaFile metaFile = this.getLoadOrMakeFile(pos, true); if (metaFile == null) { @@ -173,7 +173,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider try { metaFile = FullDataMetaFile.createFromExistingFile(this, this.level, fileToLoad); - this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.sectionDetailLevel)); + this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.getDetailLevel())); this.metaFileBySectionPos.put(pos, metaFile); return metaFile; } @@ -208,7 +208,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider return null; } - this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.sectionDetailLevel)); + this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.getDetailLevel())); // This is a CAS with expected null value. FullDataMetaFile metaFileCas = this.metaFileBySectionPos.putIfAbsent(pos, metaFile); @@ -225,10 +225,10 @@ public class FullDataFileHandler implements IFullDataSourceProvider DhSectionPos effectivePos, DhSectionPos posAreaToGet, ArrayList preexistingFiles, ArrayList missingFilePositions) { - byte sectionDetail = posAreaToGet.sectionDetailLevel; + byte sectionDetail = posAreaToGet.getDetailLevel(); boolean allEmpty = true; - final DhSectionPos subPos = new DhSectionPos((byte)0, 0, 0); + final DhSectionPos.DhMutableSectionPos subPos = new DhSectionPos.DhMutableSectionPos((byte)0, 0, 0); // get all existing files for this position outerLoop: @@ -294,7 +294,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider // we have reached a populated leaf node in the quad tree preexistingFiles.add(metaFile); } - else if (childPos.sectionDetailLevel == this.minDetailLevel) + else if (childPos.getDetailLevel() == this.minDetailLevel) { // we have reached an empty leaf node in the quad tree missingFilePositions.add(childPos); @@ -334,7 +334,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider metaFile.addToWriteQueue(chunkData); } - if (sectionPos.sectionDetailLevel <= this.topDetailLevelRef.get()) + if (sectionPos.getDetailLevel() <= this.topDetailLevelRef.get()) { // recursively attempt to get the meta file for this position this.writeChunkDataToMetaFile(sectionPos.getParentPos(), chunkData); @@ -369,7 +369,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider protected IIncompleteFullDataSource makeEmptyDataSource(DhSectionPos pos) { - return pos.sectionDetailLevel <= HighDetailIncompleteFullDataSource.MAX_SECTION_DETAIL ? + return pos.getDetailLevel() <= HighDetailIncompleteFullDataSource.MAX_SECTION_DETAIL ? HighDetailIncompleteFullDataSource.createEmpty(pos) : LowDetailIncompleteFullDataSource.createEmpty(pos); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataMetaFile.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataMetaFile.java index 56eaf760d..858f084e5 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataMetaFile.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/FullDataMetaFile.java @@ -431,7 +431,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I @Override public void debugRender(DebugRenderer debugRenderer) { - if (this.pos.sectionDetailLevel > DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL) + if (this.pos.getDetailLevel() > DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL) { return; } @@ -555,7 +555,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I new DataObjSoftTracker(this, fullDataSource); } - if (this.pos.sectionDetailLevel == DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL) + if (this.pos.getDetailLevel() == DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL) { DebugRenderer.makeParticle(new DebugRenderer.BoxParticle( new DebugRenderer.Box(this.pos, 64f, 72f, 0.03f, Color.green.darker()), diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/metaData/AbstractMetaDataContainerFile.java b/core/src/main/java/com/seibel/distanthorizons/core/file/metaData/AbstractMetaDataContainerFile.java index 168bae813..846e1b71c 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/metaData/AbstractMetaDataContainerFile.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/metaData/AbstractMetaDataContainerFile.java @@ -25,7 +25,6 @@ import java.nio.channels.Channels; import java.nio.channels.ClosedChannelException; import java.nio.channels.FileChannel; import java.nio.file.*; -import java.util.concurrent.locks.ReentrantLock; import java.util.zip.Adler32; import java.util.zip.CheckedOutputStream; @@ -231,11 +230,11 @@ public abstract class AbstractMetaDataContainerFile fileChannel.position(0); ByteBuffer buffer = ByteBuffer.allocate(METADATA_SIZE_IN_BYTES); buffer.putInt(METADATA_IDENTITY_BYTES); - buffer.putInt(this.pos.sectionX); + buffer.putInt(this.pos.getX()); buffer.putInt(Integer.MIN_VALUE); // Unused - y pos - buffer.putInt(this.pos.sectionZ); + buffer.putInt(this.pos.getZ()); buffer.putInt(this.baseMetaData.checksum); - buffer.put(this.pos.sectionDetailLevel); + buffer.put(this.pos.getDetailLevel()); buffer.put(this.baseMetaData.dataLevel); buffer.put(this.baseMetaData.binaryDataFormatVersion); buffer.put(this.baseMetaData.worldGenStep != null ? this.baseMetaData.worldGenStep.value : EDhApiWorldGenerationStep.EMPTY.value); // TODO this null check shouldn't be necessary diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/renderfile/RenderDataMetaFile.java b/core/src/main/java/com/seibel/distanthorizons/core/file/renderfile/RenderDataMetaFile.java index 3d4de5638..60991802a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/renderfile/RenderDataMetaFile.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/renderfile/RenderDataMetaFile.java @@ -197,7 +197,7 @@ public class RenderDataMetaFile extends AbstractMetaDataContainerFile implements // create an empty render source - byte dataDetailLevel = (byte) (this.pos.sectionDetailLevel - ColumnRenderSource.SECTION_SIZE_OFFSET); + byte dataDetailLevel = (byte) (this.pos.getDetailLevel() - ColumnRenderSource.SECTION_SIZE_OFFSET); int verticalSize = Config.Client.Advanced.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(dataDetailLevel); ColumnRenderSource newColumnRenderSource = new ColumnRenderSource(this.pos, verticalSize, this.clientLevel.getMinY()); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/renderfile/RenderSourceFileHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/file/renderfile/RenderSourceFileHandler.java index 0b5f4bb4c..9dc6a8bdc 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/renderfile/RenderSourceFileHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/renderfile/RenderSourceFileHandler.java @@ -23,7 +23,6 @@ import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.ChunkSizedF import com.seibel.distanthorizons.core.file.structure.AbstractSaveStructure; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.logging.f3.F3Screen; -import com.seibel.distanthorizons.core.pos.DhLodPos; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderSource; import com.seibel.distanthorizons.core.file.fullDatafile.IFullDataSourceProvider; @@ -98,11 +97,11 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider MetaFileScanUtil.IAddUnloadedFileFunc addUnloadedFileFunc = (pos, file) -> { this.unloadedFileBySectionPos.put(pos, file); - this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.sectionDetailLevel)); + this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.getDetailLevel())); }; MetaFileScanUtil.IAddLoadedMetaFileFunc addLoadedMetaFileFunc = (pos, loadedMetaFile) -> { - this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.sectionDetailLevel)); + this.topDetailLevelRef.updateAndGet(oldDetailLevel -> Math.max(oldDetailLevel, pos.getDetailLevel())); this.metaFileBySectionPos.put(pos, (RenderDataMetaFile) loadedMetaFile); }; @@ -195,7 +194,7 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider try { metaFile = RenderDataMetaFile.createFromExistingFile(this.fullDataSourceProvider, this.clientLevel, fileToLoad); - this.topDetailLevelRef.updateAndGet(currentTopDetailLevel -> Math.max(currentTopDetailLevel, pos.sectionDetailLevel)); + this.topDetailLevelRef.updateAndGet(currentTopDetailLevel -> Math.max(currentTopDetailLevel, pos.getDetailLevel())); this.metaFileBySectionPos.put(pos, metaFile); return metaFile; } @@ -221,7 +220,7 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider // due to a rare issue where the file may already exist but isn't in the file list metaFile = RenderDataMetaFile.createFromExistingOrNewFile(this.clientLevel, this.fullDataSourceProvider, pos, this.computeRenderFilePath(pos)); - this.topDetailLevelRef.updateAndGet(newDetailLevel -> Math.max(newDetailLevel, pos.sectionDetailLevel)); + this.topDetailLevelRef.updateAndGet(newDetailLevel -> Math.max(newDetailLevel, pos.getDetailLevel())); // Compare And Swap to handle a concurrency issue where multiple threads created the same Meta File at the same time RenderDataMetaFile metaFileCas = this.metaFileBySectionPos.putIfAbsent(pos, metaFile); @@ -256,14 +255,14 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider DhSectionPos boundingPos = chunk.getSectionPos(); DhSectionPos minSectionPos = boundingPos.convertNewToDetailLevel(sectionDetailLevel); - DhSectionPos fileSectionPos = new DhSectionPos((byte)0, 0, 0); + DhSectionPos.DhMutableSectionPos fileSectionPos = new DhSectionPos.DhMutableSectionPos((byte)0, 0, 0); - int width = (sectionDetailLevel > boundingPos.sectionDetailLevel) ? 1 : boundingPos.getWidthCountForLowerDetailedSection(sectionDetailLevel); + int width = (sectionDetailLevel > boundingPos.getDetailLevel()) ? 1 : boundingPos.getWidthCountForLowerDetailedSection(sectionDetailLevel); for (int xOffset = 0; xOffset < width; xOffset++) { for (int zOffset = 0; zOffset < width; zOffset++) { - fileSectionPos.mutate(sectionDetailLevel, minSectionPos.sectionX + xOffset, minSectionPos.sectionZ + zOffset); + fileSectionPos.mutate(sectionDetailLevel, minSectionPos.getX() + xOffset, minSectionPos.getZ() + zOffset); RenderDataMetaFile metaFile = this.metaFileBySectionPos.get(fileSectionPos); // bypass the getLoadOrMakeFile() since we only want cached files. if (metaFile != null) { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java index b32426a42..3cf6f863b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldGenerationQueue.java @@ -28,7 +28,6 @@ import com.seibel.distanthorizons.core.generation.tasks.*; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.pos.DhBlockPos2D; import com.seibel.distanthorizons.core.pos.DhChunkPos; -import com.seibel.distanthorizons.core.pos.DhLodPos; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.config.Config; import com.seibel.distanthorizons.core.dataObjects.transformers.LodDataBuilder; @@ -45,7 +44,6 @@ import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; import org.apache.logging.log4j.Logger; import java.awt.*; -import java.io.Closeable; import java.util.*; import java.util.concurrent.*; import java.util.function.Consumer; @@ -159,7 +157,7 @@ public class WorldGenerationQueue implements IWorldGenerationQueue, IDebugRender } // Assert that the data at least can fill in 1 single ChunkSizedFullDataAccessor - LodUtil.assertTrue(pos.sectionDetailLevel > requiredDataDetail + LodUtil.CHUNK_DETAIL_LEVEL); + LodUtil.assertTrue(pos.getDetailLevel() > requiredDataDetail + LodUtil.CHUNK_DETAIL_LEVEL); //if (this.waitingTaskQuadTree.isSectionPosInBounds(requestPos)) @@ -393,14 +391,14 @@ public class WorldGenerationQueue implements IWorldGenerationQueue, IDebugRender // split up the task and add each one to the tree LinkedList> childFutures = new LinkedList<>(); - DhSectionPos sectionPos = new DhSectionPos(closestTask.pos.sectionDetailLevel, closestTask.pos.sectionX, closestTask.pos.sectionZ); + DhSectionPos sectionPos = new DhSectionPos(closestTask.pos.getDetailLevel(), closestTask.pos.getX(), closestTask.pos.getZ()); WorldGenTask finalClosestTask = closestTask; sectionPos.forEachChild((childDhSectionPos) -> { CompletableFuture newFuture = new CompletableFuture<>(); childFutures.add(newFuture); - WorldGenTask newGenTask = new WorldGenTask(childDhSectionPos, childDhSectionPos.sectionDetailLevel, finalClosestTask.taskTracker, newFuture); + WorldGenTask newGenTask = new WorldGenTask(childDhSectionPos, childDhSectionPos.getDetailLevel(), finalClosestTask.taskTracker, newFuture); waitingTasks.put(newGenTask.pos, newGenTask); //this.waitingTaskQuadTree.setValue(new DhSectionPos(childDhSectionPos.sectionDetailLevel, childDhSectionPos.sectionX, childDhSectionPos.sectionZ), newGenTask); @@ -421,7 +419,7 @@ public class WorldGenerationQueue implements IWorldGenerationQueue, IDebugRender { byte taskDetailLevel = inProgressTaskGroup.group.dataDetail; DhSectionPos taskPos = inProgressTaskGroup.group.pos; - byte granularity = (byte) (taskPos.sectionDetailLevel - taskDetailLevel); + byte granularity = (byte) (taskPos.getDetailLevel() - taskDetailLevel); LodUtil.assertTrue(granularity >= this.minGranularity && granularity <= this.maxGranularity); LodUtil.assertTrue(taskDetailLevel >= this.smallestDataDetail && taskDetailLevel <= this.largestDataDetail); @@ -436,7 +434,7 @@ public class WorldGenerationQueue implements IWorldGenerationQueue, IDebugRender //StackTraceElement[] stackTrace = this.alreadyGeneratedPosHashSet.get(inProgressTaskGroup.group.pos); // sending a success result is necessary to make sure the render sections are reloaded correctly - inProgressTaskGroup.group.worldGenTasks.forEach(worldGenTask -> worldGenTask.future.complete(WorldGenResult.CreateSuccess(new DhSectionPos(granularity, taskPos.sectionX, taskPos.sectionZ)))); + inProgressTaskGroup.group.worldGenTasks.forEach(worldGenTask -> worldGenTask.future.complete(WorldGenResult.CreateSuccess(new DhSectionPos(granularity, taskPos.getX(), taskPos.getZ())))); return; } this.alreadyGeneratedPosHashSet.put(inProgressTaskGroup.group.pos, Thread.currentThread().getStackTrace()); @@ -470,7 +468,7 @@ public class WorldGenerationQueue implements IWorldGenerationQueue, IDebugRender else { //LOGGER.info("Section generation at "+pos+" completed"); - inProgressTaskGroup.group.worldGenTasks.forEach(worldGenTask -> worldGenTask.future.complete(WorldGenResult.CreateSuccess(new DhSectionPos(granularity, taskPos.sectionX, taskPos.sectionZ)))); + inProgressTaskGroup.group.worldGenTasks.forEach(worldGenTask -> worldGenTask.future.complete(WorldGenResult.CreateSuccess(new DhSectionPos(granularity, taskPos.getX(), taskPos.getZ())))); } boolean worked = this.inProgressGenTasksByLodPos.remove(taskPos, inProgressTaskGroup); LodUtil.assertTrue(worked); @@ -686,7 +684,7 @@ public class WorldGenerationQueue implements IWorldGenerationQueue, IDebugRender private boolean canGeneratePos(byte worldGenTaskGroupDetailLevel /*when in doubt use 0*/ , DhSectionPos taskPos) { - byte granularity = (byte) (taskPos.sectionDetailLevel - worldGenTaskGroupDetailLevel); + byte granularity = (byte) (taskPos.getDetailLevel() - worldGenTaskGroupDetailLevel); return (granularity >= this.minGranularity && granularity <= this.maxGranularity); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java index 2fa741570..ef3370411 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java @@ -59,7 +59,7 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel public void saveWrites(ChunkSizedFullDataAccessor data) { DhSectionPos pos = data.getSectionPos(); - pos.convertSelfToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET); + pos = pos.convertNewToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET); this.getFileHandler().writeChunkDataToFile(pos, data); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhLodPos.java b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhLodPos.java index 76cfdb4c3..21273d79a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhLodPos.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhLodPos.java @@ -47,7 +47,7 @@ public class DhLodPos implements Comparable this.x = x; this.z = z; } - public DhLodPos(DhSectionPos sectionPos) { this(sectionPos.sectionDetailLevel, sectionPos.sectionX, sectionPos.sectionZ); } + public DhLodPos(DhSectionPos sectionPos) { this(sectionPos.getDetailLevel(), sectionPos.getX(), sectionPos.getZ()); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhSectionPos.java b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhSectionPos.java index 44d4019b4..5753e9b5b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/pos/DhSectionPos.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/pos/DhSectionPos.java @@ -41,7 +41,6 @@ import java.util.function.Consumer; * With those thoughts in mind we decided on a smallest section size of 32 data points square (IE 2x2 chunks). * * @author Leetom - * @version 2022-11-6 */ public class DhSectionPos { @@ -56,12 +55,12 @@ public class DhSectionPos public final static byte SECTION_REGION_DETAIL_LEVEL = SECTION_MINIMUM_DETAIL_LEVEL + LodUtil.REGION_DETAIL_LEVEL; - public byte sectionDetailLevel; + protected byte detailLevel; /** in a sectionDetailLevel grid */ - public int sectionX; + protected int x; /** in a sectionDetailLevel grid */ - public int sectionZ; + protected int z; @@ -69,11 +68,11 @@ public class DhSectionPos // constructors // //==============// - public DhSectionPos(byte sectionDetailLevel, int sectionX, int sectionZ) + public DhSectionPos(byte detailLevel, int x, int z) { - this.sectionDetailLevel = sectionDetailLevel; - this.sectionX = sectionX; - this.sectionZ = sectionZ; + this.detailLevel = detailLevel; + this.x = x; + this.z = z; } public DhSectionPos(DhBlockPos blockPos) @@ -95,9 +94,9 @@ public class DhSectionPos public DhSectionPos(byte detailLevel, DhLodPos dhLodPos) { - this.sectionDetailLevel = detailLevel; - this.sectionX = dhLodPos.x; - this.sectionZ = dhLodPos.z; + this.detailLevel = detailLevel; + this.x = dhLodPos.x; + this.z = dhLodPos.z; } @@ -106,36 +105,6 @@ public class DhSectionPos // converters // //============// - /** - * Overwrites this section pos with the given input.
- * Can be useful to prevent duplicate allocations in high traffic loops but should - * be used sparingly as it could accidentally cause bugs due to unexpected modifications. - */ - public void mutate(byte sectionDetailLevel, int sectionX, int sectionZ) - { - this.sectionDetailLevel = sectionDetailLevel; - this.sectionX = sectionX; - this.sectionZ = sectionZ; - } - - /** uses the absolute detail level aka detail levels like {@link LodUtil#CHUNK_DETAIL_LEVEL} instead of the dhSectionPos detailLevels. */ - public void convertSelfToDetailLevel(byte newDetailLevel) - { - // logic originally taken from DhLodPos - if (newDetailLevel >= this.sectionDetailLevel) - { - this.sectionX = Math.floorDiv(this.sectionX, BitShiftUtil.powerOfTwo(newDetailLevel - this.sectionDetailLevel)); - this.sectionZ = Math.floorDiv(this.sectionZ, BitShiftUtil.powerOfTwo(newDetailLevel - this.sectionDetailLevel)); - } - else - { - this.sectionX = this.sectionX * BitShiftUtil.powerOfTwo(this.sectionDetailLevel - newDetailLevel); - this.sectionZ = this.sectionZ * BitShiftUtil.powerOfTwo(this.sectionDetailLevel - newDetailLevel); - } - - this.sectionDetailLevel = newDetailLevel; - } - /** * uses the absolute detail level aka detail levels like {@link LodUtil#CHUNK_DETAIL_LEVEL} instead of the dhSectionPos detailLevels. * @@ -143,12 +112,41 @@ public class DhSectionPos */ public DhSectionPos convertNewToDetailLevel(byte newSectionDetailLevel) { - DhSectionPos newPos = new DhSectionPos(this.sectionDetailLevel, this.sectionX, this.sectionZ); + DhSectionPos newPos = new DhSectionPos(this.detailLevel, this.x, this.z); newPos.convertSelfToDetailLevel(newSectionDetailLevel); return newPos; } + /** uses the absolute detail level aka detail levels like {@link LodUtil#CHUNK_DETAIL_LEVEL} instead of the dhSectionPos detailLevels. */ + protected void convertSelfToDetailLevel(byte newDetailLevel) + { + // logic originally taken from DhLodPos + if (newDetailLevel >= this.detailLevel) + { + this.x = Math.floorDiv(this.x, BitShiftUtil.powerOfTwo(newDetailLevel - this.detailLevel)); + this.z = Math.floorDiv(this.z, BitShiftUtil.powerOfTwo(newDetailLevel - this.detailLevel)); + } + else + { + this.x = this.x * BitShiftUtil.powerOfTwo(this.detailLevel - newDetailLevel); + this.z = this.z * BitShiftUtil.powerOfTwo(this.detailLevel - newDetailLevel); + } + + this.detailLevel = newDetailLevel; + } + + + + //==================// + // property getters // + //==================// + + public byte getDetailLevel() { return this.detailLevel; } + + public int getX() { return this.x; } + public int getZ() { return this.z; } + //=========// @@ -156,16 +154,16 @@ public class DhSectionPos //=========// /** @return the corner with the smallest X and Z coordinate */ - public DhLodPos getMinCornerLodPos() { return this.getMinCornerLodPos((byte) (this.sectionDetailLevel - 1)); } + public DhLodPos getMinCornerLodPos() { return this.getMinCornerLodPos((byte) (this.detailLevel - 1)); } /** @return the corner with the smallest X and Z coordinate */ public DhLodPos getMinCornerLodPos(byte returnDetailLevel) { - LodUtil.assertTrue(returnDetailLevel <= this.sectionDetailLevel, "returnDetailLevel must be less than sectionDetail"); + LodUtil.assertTrue(returnDetailLevel <= this.detailLevel, "returnDetailLevel must be less than sectionDetail"); - byte offset = (byte) (this.sectionDetailLevel - returnDetailLevel); + byte offset = (byte) (this.detailLevel - returnDetailLevel); return new DhLodPos(returnDetailLevel, - this.sectionX * BitShiftUtil.powerOfTwo(offset), - this.sectionZ * BitShiftUtil.powerOfTwo(offset)); + this.x * BitShiftUtil.powerOfTwo(offset), + this.z * BitShiftUtil.powerOfTwo(offset)); } /** @@ -180,13 +178,13 @@ public class DhSectionPos */ public int getWidthCountForLowerDetailedSection(byte returnDetailLevel) { - LodUtil.assertTrue(returnDetailLevel <= this.sectionDetailLevel, "returnDetailLevel must be less than sectionDetail"); - byte offset = (byte) (this.sectionDetailLevel - returnDetailLevel); + LodUtil.assertTrue(returnDetailLevel <= this.detailLevel, "returnDetailLevel must be less than sectionDetail"); + byte offset = (byte) (this.detailLevel - returnDetailLevel); return BitShiftUtil.powerOfTwo(offset); } /** @return how wide this section is in blocks */ - public int getBlockWidth() { return BitShiftUtil.powerOfTwo(this.sectionDetailLevel); } + public int getBlockWidth() { return BitShiftUtil.powerOfTwo(this.detailLevel); } public DhBlockPos2D getCenterBlockPos() { return new DhBlockPos2D(this.getCenterBlockPosX(), this.getCenterBlockPosZ()); } @@ -195,9 +193,9 @@ public class DhSectionPos public int getCenterBlockPosZ() { return this.getCenterBlockPos(false); } private int getCenterBlockPos(boolean returnX) { - int centerBlockPos = returnX ? this.sectionX : this.sectionZ; + int centerBlockPos = returnX ? this.x : this.z; - if (this.sectionDetailLevel == 0) + if (this.detailLevel == 0) { // already at block detail level, no conversion necessary return centerBlockPos; @@ -205,12 +203,12 @@ public class DhSectionPos // we can't get the center of the position at block level, only attempt to get the position offset for detail levels above 0 int positionOffset = 0; - if (this.sectionDetailLevel != 1) + if (this.detailLevel != 1) { - positionOffset = BitShiftUtil.powerOfTwo(this.sectionDetailLevel - 1); + positionOffset = BitShiftUtil.powerOfTwo(this.detailLevel - 1); } - return (centerBlockPos * BitShiftUtil.powerOfTwo(this.sectionDetailLevel)) + positionOffset; + return (centerBlockPos * BitShiftUtil.powerOfTwo(this.detailLevel)) + positionOffset; } @@ -236,31 +234,31 @@ public class DhSectionPos { throw new IllegalArgumentException("child0to3 must be between 0 and 3"); } - if (this.sectionDetailLevel <= 0) + if (this.detailLevel <= 0) { throw new IllegalStateException("section detail must be greater than 0"); } - return new DhSectionPos((byte) (this.sectionDetailLevel - 1), - this.sectionX * 2 + (child0to3 & 1), - this.sectionZ * 2 + BitShiftUtil.half(child0to3 & 2)); + return new DhSectionPos((byte) (this.detailLevel - 1), + this.x * 2 + (child0to3 & 1), + this.z * 2 + BitShiftUtil.half(child0to3 & 2)); } /** Returns this position's child index in its parent */ - public int getChildIndexOfParent() { return (this.sectionX & 1) + BitShiftUtil.square(this.sectionZ & 1); } + public int getChildIndexOfParent() { return (this.x & 1) + BitShiftUtil.square(this.z & 1); } - public DhSectionPos getParentPos() { return new DhSectionPos((byte) (this.sectionDetailLevel + 1), BitShiftUtil.half(this.sectionX), BitShiftUtil.half(this.sectionZ)); } + public DhSectionPos getParentPos() { return new DhSectionPos((byte) (this.detailLevel + 1), BitShiftUtil.half(this.x), BitShiftUtil.half(this.z)); } public DhSectionPos getAdjacentPos(EDhDirection dir) { - return new DhSectionPos(this.sectionDetailLevel, - this.sectionX + dir.getNormal().x, - this.sectionZ + dir.getNormal().z); + return new DhSectionPos(this.detailLevel, + this.x + dir.getNormal().x, + this.z + dir.getNormal().z); } - public DhLodPos getSectionBBoxPos() { return new DhLodPos(this.sectionDetailLevel, this.sectionX, this.sectionZ); } + public DhLodPos getSectionBBoxPos() { return new DhLodPos(this.detailLevel, this.x, this.z); } @@ -275,17 +273,17 @@ public class DhSectionPos { return true; } - else if (this.sectionDetailLevel == other.sectionDetailLevel) + else if (this.detailLevel == other.detailLevel) { return false; } - else if (this.sectionDetailLevel > other.sectionDetailLevel) + else if (this.detailLevel > other.detailLevel) { - return this.equals(other.convertNewToDetailLevel(this.sectionDetailLevel)); + return this.equals(other.convertNewToDetailLevel(this.detailLevel)); } else { - return other.equals(this.convertNewToDetailLevel(other.sectionDetailLevel)); + return other.equals(this.convertNewToDetailLevel(other.detailLevel)); } } @@ -319,7 +317,7 @@ public class DhSectionPos /** Applies the given consumer to all children of the position at the given section detail level. */ public void forEachChildAtLevel(byte sectionDetailLevel, Consumer callback) { - if (sectionDetailLevel == this.sectionDetailLevel) + if (sectionDetailLevel == this.detailLevel) { callback.accept(this); return; @@ -338,7 +336,7 @@ public class DhSectionPos //===============// /** Serialize() is different from toString() as it must NEVER be changed, and should be in a short format */ - public String serialize() { return "[" + this.sectionDetailLevel + ',' + this.sectionX + ',' + this.sectionZ + ']'; } + public String serialize() { return "[" + this.detailLevel + ',' + this.x + ',' + this.z + ']'; } @Nullable public static DhSectionPos deserialize(String value) @@ -357,7 +355,7 @@ public class DhSectionPos //===========// @Override - public String toString() { return "{" + this.sectionDetailLevel + "*" + this.sectionX + "," + this.sectionZ + "}"; } + public String toString() { return "{" + this.detailLevel + "*" + this.x + "," + this.z + "}"; } @Override public boolean equals(Object obj) @@ -372,17 +370,77 @@ public class DhSectionPos } DhSectionPos that = (DhSectionPos) obj; - return this.sectionDetailLevel == that.sectionDetailLevel && - this.sectionX == that.sectionX && - this.sectionZ == that.sectionZ; + return this.detailLevel == that.detailLevel && + this.x == that.x && + this.z == that.z; } @Override public int hashCode() { - return Integer.hashCode(this.sectionDetailLevel) ^ // XOR - Integer.hashCode(this.sectionX) ^ // XOR - Integer.hashCode(this.sectionZ); + return Integer.hashCode(this.detailLevel) ^ // XOR + Integer.hashCode(this.x) ^ // XOR + Integer.hashCode(this.z); + } + + + + //=============// + // sub classes // + //=============// + + /** + * Identical to {@link DhSectionPos} except it is mutable. + * See {@link DhSectionPos} for full documentation. + * + * @see DhSectionPos + */ + public static class DhMutableSectionPos extends DhSectionPos + { + + //==============// + // constructors // + //==============// + + public DhMutableSectionPos(byte sectionDetailLevel, int sectionX, int sectionZ) { super(sectionDetailLevel, sectionX, sectionZ); } + public DhMutableSectionPos(DhBlockPos blockPos) { super(blockPos); } + public DhMutableSectionPos(DhBlockPos2D blockPos) { super(blockPos); } + public DhMutableSectionPos(DhChunkPos chunkPos) { super(chunkPos); } + public DhMutableSectionPos(byte detailLevel, DhLodPos dhLodPos) { super(detailLevel, dhLodPos); } + + + + //============// + // converters // + //============// + + /** + * Overwrites this section pos with the given input.
+ * Can be useful to prevent duplicate allocations in high traffic loops but should + * be used sparingly as it could accidentally cause bugs due to unexpected modifications. + */ + public void mutate(byte sectionDetailLevel, int sectionX, int sectionZ) + { + this.detailLevel = sectionDetailLevel; + this.x = sectionX; + this.z = sectionZ; + } + + @Override + public void convertSelfToDetailLevel(byte newDetailLevel) { super.convertSelfToDetailLevel(newDetailLevel); } + + + + //==================// + // property getters // + //==================// + + public void setDetailLevel(byte sectionDetailLevel) { this.detailLevel = sectionDetailLevel; } + + public void setX(int sectionX) { this.x = sectionX; } + + public void setZ(int sectionZ) { this.z = sectionZ; } + } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java index 8caa1641e..53dee52a2 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/LodQuadTree.java @@ -143,7 +143,7 @@ public class LodQuadTree extends QuadTree implements AutoClose { // walk up the tree until we hit the root node // this is done so any high detail changes flow up to the lower detail render sections as well - while (pos.sectionDetailLevel <= this.treeMinDetailLevel) + while (pos.getDetailLevel() <= this.treeMinDetailLevel) { try { @@ -223,7 +223,7 @@ public class LodQuadTree extends QuadTree implements AutoClose expectedDetailLevel += DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL; - if (sectionPos.sectionDetailLevel > expectedDetailLevel) + if (sectionPos.getDetailLevel() > expectedDetailLevel) { // section detail level too high // boolean canThisPosRender = renderSection.isRenderingEnabled(); @@ -273,7 +273,7 @@ public class LodQuadTree extends QuadTree implements AutoClose } } // TODO this should only equal the expected detail level, the (expectedDetailLevel-1) is a temporary fix to prevent corners from being cut out - else if (sectionPos.sectionDetailLevel == expectedDetailLevel || sectionPos.sectionDetailLevel == expectedDetailLevel - 1) + else if (sectionPos.getDetailLevel() == expectedDetailLevel || sectionPos.getDetailLevel() == expectedDetailLevel - 1) { // this is the detail level we want to render // // prepare this section for rendering diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java b/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java index 18e06d240..eaa32502e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/LodRenderSection.java @@ -160,7 +160,7 @@ public class LodRenderSection implements IDebugRenderable public void reload(ILodRenderSourceProvider renderDataProvider) { // debug rendering - if (this.pos.sectionDetailLevel == DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL) + if (this.pos.getDetailLevel() == DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL) { DebugRenderer.makeParticle( new DebugRenderer.BoxParticle( @@ -324,7 +324,7 @@ public class LodRenderSection implements IDebugRenderable if (this.canBuildBuffer()) { // debug - if (this.pos.sectionDetailLevel == DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL) + if (this.pos.getDetailLevel() == DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL) { DebugRenderer.makeParticle( new DebugRenderer.BoxParticle( diff --git a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java index c4f51f256..502537ce2 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/render/RenderBufferHandler.java @@ -161,7 +161,7 @@ public class RenderBufferHandler return abPosDifference; } - return loadedBufferA.pos.sectionDetailLevel - loadedBufferB.pos.sectionDetailLevel; // If all else fails, sort by detail + return loadedBufferA.pos.getDetailLevel() - loadedBufferB.pos.getDetailLevel(); // If all else fails, sort by detail }; // Build the sorted list diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadNode.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadNode.java index 70aa58e97..a8794be82 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadNode.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadNode.java @@ -183,17 +183,17 @@ public class QuadNode throw new IllegalArgumentException("Input section pos " + inputSectionPos + " outside of this quadNode's pos: " + this.sectionPos + ", this node's blockPos: " + this.sectionPos.convertNewToDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL) + " block width: " + this.sectionPos.getBlockWidth() + " input detail level: " + inputSectionPos.convertNewToDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL) + " width: " + inputSectionPos.getBlockWidth()); } - if (inputSectionPos.sectionDetailLevel > this.sectionPos.sectionDetailLevel) + if (inputSectionPos.getDetailLevel() > this.sectionPos.getDetailLevel()) { - throw new IllegalArgumentException("detail level higher than this node. Node Detail level: " + this.sectionPos.sectionDetailLevel + " input detail level: " + inputSectionPos.sectionDetailLevel); + throw new IllegalArgumentException("detail level higher than this node. Node Detail level: " + this.sectionPos.getDetailLevel() + " input detail level: " + inputSectionPos.getDetailLevel()); } - if (inputSectionPos.sectionDetailLevel == this.sectionPos.sectionDetailLevel && !inputSectionPos.equals(this.sectionPos)) + if (inputSectionPos.getDetailLevel() == this.sectionPos.getDetailLevel() && !inputSectionPos.equals(this.sectionPos)) { throw new IllegalArgumentException("Node and input detail level are equal, however positions are not; this tree doesn't contain the requested position. Node pos: " + this.sectionPos + ", input pos: " + inputSectionPos); } - if (inputSectionPos.sectionDetailLevel < this.minimumDetailLevel) + if (inputSectionPos.getDetailLevel() < this.minimumDetailLevel) { throw new IllegalArgumentException("Input position is requesting a detail level lower than what this node can provide. Node minimum detail level: " + this.minimumDetailLevel + ", input pos: " + inputSectionPos); } @@ -201,7 +201,7 @@ public class QuadNode // get/set logic - if (inputSectionPos.sectionDetailLevel == this.sectionPos.sectionDetailLevel) + if (inputSectionPos.getDetailLevel() == this.sectionPos.getDetailLevel()) { // this node is the requested position if (replaceValue) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java index e40f4f2ab..9dcaf72e7 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/QuadTree.java @@ -130,8 +130,8 @@ public class QuadTree DhSectionPos rootPos = pos.convertNewToDetailLevel(this.treeMinDetailLevel); - int ringListPosX = rootPos.sectionX; - int ringListPosZ = rootPos.sectionZ; + int ringListPosX = rootPos.getX(); + int ringListPosZ = rootPos.getZ(); QuadNode topQuadNode = this.topRingList.get(ringListPosX, ringListPosZ); if (topQuadNode == null) @@ -163,7 +163,7 @@ public class QuadTree public boolean isSectionPosInBounds(DhSectionPos testPos) { // check if the testPos is within the detail level limits of the tree - boolean detailLevelWithinBounds = this.treeMaxDetailLevel <= testPos.sectionDetailLevel && testPos.sectionDetailLevel <= this.treeMinDetailLevel; + boolean detailLevelWithinBounds = this.treeMaxDetailLevel <= testPos.getDetailLevel() && testPos.getDetailLevel() <= this.treeMinDetailLevel; if (!detailLevelWithinBounds) { return false; @@ -175,8 +175,8 @@ public class QuadTree DhLodPos treeCornerPos = new DhLodPos((byte) 0, treeBlockCorner.x, treeBlockCorner.z); DhSectionPos inputSectionCorner = testPos.convertNewToDetailLevel((byte) 0); - DhLodPos inputCornerPos = new DhLodPos((byte) 0, inputSectionCorner.sectionX, inputSectionCorner.sectionZ); - int inputBlockWidth = BitShiftUtil.powerOfTwo(testPos.sectionDetailLevel); + DhLodPos inputCornerPos = new DhLodPos((byte) 0, inputSectionCorner.getX(), inputSectionCorner.getZ()); + int inputBlockWidth = BitShiftUtil.powerOfTwo(testPos.getDetailLevel()); return DoSquaresOverlap(treeCornerPos, this.widthInBlocks, inputCornerPos, inputBlockWidth); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/iterators/QuadNodeChildIndexIterator.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/iterators/QuadNodeChildIndexIterator.java index 77dda14d1..639f8e40a 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/iterators/QuadNodeChildIndexIterator.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/iterators/QuadNodeChildIndexIterator.java @@ -36,7 +36,7 @@ public class QuadNodeChildIndexIterator implements Iterator public QuadNodeChildIndexIterator(QuadNode parentNode, boolean returnNullChildPos) { // only get the children if this section isn't at the bottom of the tree - if (parentNode.sectionPos.sectionDetailLevel > parentNode.minimumDetailLevel) + if (parentNode.sectionPos.getDetailLevel() > parentNode.minimumDetailLevel) { // go over each child pos for (int i = 0; i < 4; i++) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/iterators/QuadTreeNodeIterator.java b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/iterators/QuadTreeNodeIterator.java index b36b4167f..13745870e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/iterators/QuadTreeNodeIterator.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/util/objects/quadTree/iterators/QuadTreeNodeIterator.java @@ -46,7 +46,7 @@ public class QuadTreeNodeIterator implements Iterator> this.onlyReturnLeafValues = onlyReturnLeafValues; // TODO the naming conversion for these are flipped in a lot of places this.highestDetailLevel = rootNode.minimumDetailLevel; - this.iteratorDetailLevel = rootNode.sectionPos.sectionDetailLevel; + this.iteratorDetailLevel = rootNode.sectionPos.getDetailLevel(); if (!this.onlyReturnLeafValues) diff --git a/core/src/test/java/tests/QuadTreeTest.java b/core/src/test/java/tests/QuadTreeTest.java index ea79698af..722dfbaec 100644 --- a/core/src/test/java/tests/QuadTreeTest.java +++ b/core/src/test/java/tests/QuadTreeTest.java @@ -649,7 +649,7 @@ public class QuadTreeTest DhSectionPos sectionPos = directChildIterator.next(); QuadNode childNode = node.getNode(sectionPos); - Assert.assertTrue("Child node recurred too low. Min detail level: " + minDetailLevel + ", node detail level: " + childNode.sectionPos.sectionDetailLevel, childNode.sectionPos.sectionDetailLevel >= minDetailLevel); + Assert.assertTrue("Child node recurred too low. Min detail level: " + minDetailLevel + ", node detail level: " + childNode.sectionPos.getDetailLevel(), childNode.sectionPos.getDetailLevel() >= minDetailLevel); recursivelyCreateNodeChildren(childNode, minDetailLevel, minimumDetailLevelReachedRef); childNodesIterated = true; @@ -657,9 +657,9 @@ public class QuadTreeTest // keep track of how far down the tree we have gone - if (node.sectionPos.sectionDetailLevel < minimumDetailLevelReachedRef.get()) + if (node.sectionPos.getDetailLevel() < minimumDetailLevelReachedRef.get()) { - minimumDetailLevelReachedRef.set(node.sectionPos.sectionDetailLevel); + minimumDetailLevelReachedRef.set(node.sectionPos.getDetailLevel()); } @@ -667,11 +667,11 @@ public class QuadTreeTest // assertions if (childNodesCreated) { - Assert.assertTrue("node children created below minimum detail level", node.sectionPos.sectionDetailLevel >= minDetailLevel); + Assert.assertTrue("node children created below minimum detail level", node.sectionPos.getDetailLevel() >= minDetailLevel); } if (childNodesIterated) { - Assert.assertTrue("node children iterated below minimum detail level", node.sectionPos.sectionDetailLevel - 1 >= minDetailLevel); + Assert.assertTrue("node children iterated below minimum detail level", node.sectionPos.getDetailLevel() - 1 >= minDetailLevel); } }