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 7969498cf..c99e77597 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 @@ -47,15 +47,17 @@ public class FullDataDownSampler ArrayList> futures; DhLodPos basePos = target.getSectionPos().getSectionBBoxPos().getCornerLodPos(CompleteFullDataSource.SECTION_SIZE_OFFSET); + + if (sectionSizeNeeded <= CompleteFullDataSource.SECTION_SIZE_OFFSET) { futures = new ArrayList<>(sectionSizeNeeded * sectionSizeNeeded); - for (int ox = 0; ox < sectionSizeNeeded; ox++) + for (int xOffset = 0; xOffset < sectionSizeNeeded; xOffset++) { - for (int oz = 0; oz < sectionSizeNeeded; oz++) + for (int zOffset = 0; zOffset < sectionSizeNeeded; zOffset++) { CompletableFuture future = provider.readAsync(new DhSectionPos( - CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox, basePos.z + oz)); + CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + xOffset, basePos.z + zOffset)); future = future.whenComplete((source, ex) -> { if (ex == null && source != null && source instanceof CompleteFullDataSource) { @@ -74,12 +76,12 @@ public class FullDataDownSampler { futures = new ArrayList<>(CompleteFullDataSource.WIDTH * CompleteFullDataSource.WIDTH); int multiplier = sectionSizeNeeded / CompleteFullDataSource.WIDTH; - for (int ox = 0; ox < CompleteFullDataSource.WIDTH; ox++) + for (int xOffset = 0; xOffset < CompleteFullDataSource.WIDTH; xOffset++) { - for (int oz = 0; oz < CompleteFullDataSource.WIDTH; oz++) + for (int zOffset = 0; zOffset < CompleteFullDataSource.WIDTH; zOffset++) { CompletableFuture future = provider.readAsync(new DhSectionPos( - CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox * multiplier, basePos.z + oz * multiplier)); + CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + xOffset * multiplier, basePos.z + zOffset * multiplier)); future = future.whenComplete((source, ex) -> { if (ex == null && source != null && source instanceof CompleteFullDataSource) { @@ -99,7 +101,7 @@ public class FullDataDownSampler public static void downSample(CompleteFullDataSource target, CompleteFullDataSource source) { - LodUtil.assertTrue(target.getSectionPos().overlaps(source.getSectionPos())); + LodUtil.assertTrue(target.getSectionPos().overlapsExactly(source.getSectionPos())); LodUtil.assertTrue(target.getDataDetailLevel() > source.getDataDetailLevel()); byte detailDiff = (byte) (target.getDataDetailLevel() - source.getDataDetailLevel()); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/accessor/ChunkSizedFullDataAccessor.java b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/accessor/ChunkSizedFullDataAccessor.java index 5f6fb61b5..350fe155e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/accessor/ChunkSizedFullDataAccessor.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/dataObjects/fullData/accessor/ChunkSizedFullDataAccessor.java @@ -20,7 +20,6 @@ package com.seibel.distanthorizons.core.dataObjects.fullData.accessor; import com.seibel.distanthorizons.core.pos.DhChunkPos; -import com.seibel.distanthorizons.core.pos.DhLodPos; import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.util.FullDataPointUtil; @@ -34,19 +33,22 @@ import com.seibel.distanthorizons.core.util.LodUtil; */ public class ChunkSizedFullDataAccessor extends FullDataArrayAccessor { - public final DhChunkPos pos; + public final DhChunkPos chunkPos; + public final DhSectionPos sectionPos; + // TODO replace this var with LodUtil.BLOCK_DETAIL_LEVEL public final byte detailLevel = LodUtil.BLOCK_DETAIL_LEVEL; - public ChunkSizedFullDataAccessor(DhChunkPos pos) + public ChunkSizedFullDataAccessor(DhChunkPos chunkPos) { - super(new FullDataPointIdMap(new DhSectionPos(pos)), + super(new FullDataPointIdMap(new DhSectionPos(chunkPos)), new long[LodUtil.CHUNK_WIDTH * LodUtil.CHUNK_WIDTH][0], LodUtil.CHUNK_WIDTH); - this.pos = pos; + this.chunkPos = chunkPos; + this.sectionPos = new DhSectionPos(LodUtil.CHUNK_DETAIL_LEVEL, this.chunkPos.x, this.chunkPos.z); } @@ -68,9 +70,9 @@ public class ChunkSizedFullDataAccessor extends FullDataArrayAccessor public long emptyCount() { return (LodUtil.CHUNK_WIDTH * LodUtil.CHUNK_WIDTH) - this.nonEmptyCount(); } - public DhLodPos getLodPos() { return new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, this.pos.x, this.pos.z); } + public DhSectionPos getSectionPos() { return this.sectionPos; } @Override - public String toString() { return this.pos + " " + this.nonEmptyCount(); } + public String toString() { return this.chunkPos + " " + this.nonEmptyCount(); } } \ No newline at end of file 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 586648c87..dbf5b573c 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 @@ -277,10 +277,10 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu @Override public void update(ChunkSizedFullDataAccessor chunkDataView) { - LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(chunkDataView.getLodPos())); + LodUtil.assertTrue(this.sectionPos.overlapsExactly(chunkDataView.getSectionPos())); if (this.getDataDetailLevel() == LodUtil.BLOCK_DETAIL_LEVEL) { - DhBlockPos2D chunkBlockPos = new DhBlockPos2D(chunkDataView.pos.x * LodUtil.CHUNK_WIDTH, chunkDataView.pos.z * LodUtil.CHUNK_WIDTH); + DhBlockPos2D chunkBlockPos = new DhBlockPos2D(chunkDataView.chunkPos.x * LodUtil.CHUNK_WIDTH, chunkDataView.chunkPos.z * LodUtil.CHUNK_WIDTH); DhBlockPos2D blockOffset = chunkBlockPos.subtract(this.sectionPos.getMinCornerLodPos().getCornerBlockPos()); LodUtil.assertTrue(blockOffset.x >= 0 && blockOffset.x < WIDTH && blockOffset.z >= 0 && blockOffset.z < WIDTH); this.isEmpty = false; @@ -303,7 +303,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu { int dataPerFull = 1 << this.getDataDetailLevel(); int fullSize = LodUtil.CHUNK_WIDTH / dataPerFull; - DhLodPos dataOffset = chunkDataView.getLodPos().getCornerLodPos(this.getDataDetailLevel()); + DhLodPos dataOffset = chunkDataView.getSectionPos().getMinCornerLodPos(this.getDataDetailLevel()); DhLodPos baseOffset = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel()); int offsetX = dataOffset.x - baseOffset.x; @@ -324,16 +324,16 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu { //FIXME: TEMPORARY int chunkPerFull = 1 << (this.getDataDetailLevel() - LodUtil.CHUNK_DETAIL_LEVEL); - if (chunkDataView.pos.x % chunkPerFull != 0 || chunkDataView.pos.z % chunkPerFull != 0) + if (chunkDataView.chunkPos.x % chunkPerFull != 0 || chunkDataView.chunkPos.z % chunkPerFull != 0) { return; } DhLodPos baseOffset = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel()); - DhLodPos dataOffset = chunkDataView.getLodPos().convertToDetailLevel(this.getDataDetailLevel()); + DhSectionPos dataOffset = chunkDataView.getSectionPos().convertNewToDetailLevel(this.getDataDetailLevel()); - int offsetX = dataOffset.x - baseOffset.x; - int offsetZ = dataOffset.z - baseOffset.z; + int offsetX = dataOffset.sectionX - baseOffset.x; + int offsetZ = dataOffset.sectionZ - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < WIDTH && offsetZ >= 0 && offsetZ < WIDTH); this.isEmpty = false; @@ -356,7 +356,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu /** Returns whether data at the given posToWrite can effect the target region file at posToTest. */ public static boolean firstDataPosCanAffectSecond(DhSectionPos posToWrite, DhSectionPos posToTest) { - if (!posToWrite.overlaps(posToTest)) + if (!posToWrite.overlapsExactly(posToTest)) { // the testPosition is outside the writePosition return false; @@ -418,7 +418,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu public void updateFromLowerCompleteSource(CompleteFullDataSource subData) { - LodUtil.assertTrue(this.sectionPos.overlaps(subData.sectionPos)); + LodUtil.assertTrue(this.sectionPos.overlapsExactly(subData.sectionPos)); LodUtil.assertTrue(subData.sectionPos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); if (!firstDataPosCanAffectSecond(this.sectionPos, subData.sectionPos)) { 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 4ca3c4600..5d0e76eca 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 @@ -456,7 +456,7 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo @Override public void update(ChunkSizedFullDataAccessor chunkDataView) { - int arrayOffset = this.calculateOffset(chunkDataView.pos.x, chunkDataView.pos.z); + int arrayOffset = this.calculateOffset(chunkDataView.chunkPos.x, chunkDataView.chunkPos.z); FullDataArrayAccessor newArray = new FullDataArrayAccessor(this.mapping, new long[this.dataPointsPerSection * this.dataPointsPerSection][], this.dataPointsPerSection); if (this.getDataDetailLevel() == chunkDataView.detailLevel) { @@ -489,7 +489,7 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo { DhSectionPos pos = fullDataSource.getSectionPos(); LodUtil.assertTrue(pos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); - LodUtil.assertTrue(pos.overlaps(this.sectionPos)); + LodUtil.assertTrue(pos.overlapsExactly(this.sectionPos)); if (fullDataSource.isEmpty()) { return; 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 799d4518e..9a43898ba 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 @@ -318,21 +318,21 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp @Override public void update(ChunkSizedFullDataAccessor data) { - LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(data.getLodPos())); + LodUtil.assertTrue(this.sectionPos.overlapsExactly(data.getSectionPos())); if (this.getDataDetailLevel() >= 4) { //FIXME: TEMPORARY int chunkPerFull = 1 << (this.getDataDetailLevel() - 4); - if (data.pos.x % chunkPerFull != 0 || data.pos.z % chunkPerFull != 0) + if (data.chunkPos.x % chunkPerFull != 0 || data.chunkPos.z % chunkPerFull != 0) { return; } DhLodPos baseOffset = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel()); - DhLodPos dataOffset = data.getLodPos().convertToDetailLevel(this.getDataDetailLevel()); - int offsetX = dataOffset.x - baseOffset.x; - int offsetZ = dataOffset.z - baseOffset.z; + DhSectionPos dataOffset = data.getSectionPos().convertNewToDetailLevel(this.getDataDetailLevel()); + int offsetX = dataOffset.sectionX - baseOffset.x; + int offsetZ = dataOffset.sectionZ - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < WIDTH && offsetZ >= 0 && offsetZ < WIDTH); this.isEmpty = false; @@ -354,7 +354,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp { DhSectionPos pos = fullDataSource.getSectionPos(); LodUtil.assertTrue(pos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); - LodUtil.assertTrue(pos.overlaps(this.sectionPos)); + LodUtil.assertTrue(pos.overlapsExactly(this.sectionPos)); if (fullDataSource.isEmpty()) { @@ -572,7 +572,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp public static boolean neededForPosition(DhSectionPos posToWrite, DhSectionPos posToTest) { - if (!posToWrite.overlaps(posToTest)) + if (!posToWrite.overlapsExactly(posToTest)) return false; if (posToTest.sectionDetailLevel > posToWrite.sectionDetailLevel) return false; 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 9b9d1a8c6..9b42652d9 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 @@ -308,7 +308,7 @@ public class ColumnRenderSource */ public boolean updateWithChunkData(ChunkSizedFullDataAccessor chunkDataView, IDhClientLevel level) { - final String errorMessagePrefix = "Unable to complete fastWrite for RenderSource pos: [" + this.sectionPos + "] and chunk pos: [" + chunkDataView.pos + "]. Error:"; + final String errorMessagePrefix = "Unable to complete fastWrite for RenderSource pos: [" + this.sectionPos + "] and chunk pos: [" + chunkDataView.chunkPos + "]. Error:"; final DhSectionPos renderSourcePos = this.getSectionPos(); @@ -316,8 +316,8 @@ public class ColumnRenderSource final int sourceBlockZ = renderSourcePos.getMinCornerLodPos().getCornerBlockPos().z; // offset between the incoming chunk data and this render source - final int blockOffsetX = (chunkDataView.pos.x * LodUtil.CHUNK_WIDTH) - sourceBlockX; - final int blockOffsetZ = (chunkDataView.pos.z * LodUtil.CHUNK_WIDTH) - sourceBlockZ; + final int blockOffsetX = (chunkDataView.chunkPos.x * LodUtil.CHUNK_WIDTH) - sourceBlockX; + final int blockOffsetZ = (chunkDataView.chunkPos.z * LodUtil.CHUNK_WIDTH) - sourceBlockZ; final int sourceDataPointBlockWidth = BitShiftUtil.powerOfTwo(this.getDataDetail()); @@ -360,27 +360,27 @@ 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.getLodPos().detailLevel) + else if (chunkDataView.detailLevel < this.getDataDetail() && this.getDataDetail() <= chunkDataView.getSectionPos().sectionDetailLevel) { this.markNotEmpty(); // multiple chunk data points converting to 1 column data point - DhLodPos dataCornerPos = chunkDataView.getLodPos().getCornerLodPos(chunkDataView.detailLevel); + DhLodPos dataCornerPos = chunkDataView.getSectionPos().getMinCornerLodPos(chunkDataView.detailLevel); DhLodPos sourceCornerPos = renderSourcePos.getMinCornerLodPos(this.getDataDetail()); DhLodPos sourceStartingChangePos = dataCornerPos.convertToDetailLevel(this.getDataDetail()); int relStartX = Math.floorMod(sourceStartingChangePos.x, this.getWidthInDataPoints()); int relStartZ = Math.floorMod(sourceStartingChangePos.z, this.getWidthInDataPoints()); int dataToSourceScale = sourceCornerPos.getWidthAtDetail(chunkDataView.detailLevel); - int columnsInChunk = chunkDataView.getLodPos().getWidthAtDetail(this.getDataDetail()); + int columnsInChunk = chunkDataView.getSectionPos().getWidthCountForLowerDetailedSection(this.getDataDetail()); - for (int ox = 0; ox < columnsInChunk; ox++) + for (int xOffset = 0; xOffset < columnsInChunk; xOffset++) { - for (int oz = 0; oz < columnsInChunk; oz++) + for (int zOffset = 0; zOffset < columnsInChunk; zOffset++) { - int relSourceX = relStartX + ox; - int relSourceZ = relStartZ + oz; + int relSourceX = relStartX + xOffset; + int relSourceZ = relStartZ + zOffset; ColumnArrayView columnArrayView = this.getVerticalDataPointView(relSourceX, relSourceZ); int hash = columnArrayView.getDataHash(); - SingleColumnFullDataAccessor fullArrayView = chunkDataView.get(ox * dataToSourceScale, oz * dataToSourceScale); + SingleColumnFullDataAccessor fullArrayView = chunkDataView.get(xOffset * dataToSourceScale, zOffset * dataToSourceScale); FullDataToRenderDataTransformer.convertColumnData(level, sourceBlockX + sourceDataPointBlockWidth * relSourceX, sourceBlockZ + sourceDataPointBlockWidth * relSourceZ, @@ -390,14 +390,14 @@ public class ColumnRenderSource } this.fillDebugFlag(relStartX, relStartZ, columnsInChunk, columnsInChunk, ColumnRenderSource.DebugSourceFlag.DIRECT); } - else if (chunkDataView.getLodPos().detailLevel < this.getDataDetail()) + else if (chunkDataView.getSectionPos().sectionDetailLevel < this.getDataDetail()) { // The entire chunk is being converted to a single column data point, possibly. - DhLodPos dataCornerPos = chunkDataView.getLodPos().getCornerLodPos(chunkDataView.detailLevel); + DhLodPos dataCornerPos = chunkDataView.getSectionPos().getMinCornerLodPos(chunkDataView.detailLevel); DhLodPos sourceCornerPos = renderSourcePos.getMinCornerLodPos(this.getDataDetail()); DhLodPos sourceStartingChangePos = dataCornerPos.convertToDetailLevel(this.getDataDetail()); - int chunksPerColumn = sourceStartingChangePos.getWidthAtDetail(chunkDataView.getLodPos().detailLevel); - if (chunkDataView.getLodPos().x % chunksPerColumn != 0 || chunkDataView.getLodPos().z % chunksPerColumn != 0) + int chunksPerColumn = sourceStartingChangePos.getWidthAtDetail(chunkDataView.getSectionPos().sectionDetailLevel); + if (chunkDataView.getSectionPos().sectionX % chunksPerColumn != 0 || chunkDataView.getSectionPos().sectionZ % chunksPerColumn != 0) { return false; // not a multiple of the column size, so no change } 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 1b3f4a4d8..8462c8c53 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 @@ -228,6 +228,8 @@ public class FullDataFileHandler implements IFullDataSourceProvider byte sectionDetail = posAreaToGet.sectionDetailLevel; boolean allEmpty = true; + final DhSectionPos subPos = new DhSectionPos((byte)0, 0, 0); + // get all existing files for this position outerLoop: while (--sectionDetail >= this.minDetailLevel) @@ -239,8 +241,8 @@ public class FullDataFileHandler implements IFullDataSourceProvider { for (int zOffset = 0; zOffset < count; zOffset++) { - DhSectionPos subPos = new DhSectionPos(sectionDetail, xOffset + minPos.x, zOffset + minPos.z); - LodUtil.assertTrue(posAreaToGet.overlaps(effectivePos) && subPos.overlaps(posAreaToGet)); + subPos.mutate(sectionDetail, xOffset + minPos.x, zOffset + minPos.z); + LodUtil.assertTrue(posAreaToGet.overlapsExactly(effectivePos) && subPos.overlapsExactly(posAreaToGet)); //TODO: The following check is temporary as we only sample corner points, which means // on a very different level, we may not need the entire section at all. @@ -317,11 +319,11 @@ public class FullDataFileHandler implements IFullDataSourceProvider @Override public void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataAccessor chunkDataView) { - DhLodPos chunkPos = chunkDataView.getLodPos(); - LodUtil.assertTrue(chunkPos.overlapsExactly(sectionPos.getSectionBBoxPos()), "Chunk " + chunkPos + " does not overlap section " + sectionPos); + DhSectionPos chunkSectionPos = chunkDataView.getSectionPos(); + LodUtil.assertTrue(chunkSectionPos.overlapsExactly(sectionPos), "Chunk " + chunkSectionPos + " does not overlap section " + sectionPos); - chunkPos = chunkPos.convertToDetailLevel((byte) this.minDetailLevel); - this.writeChunkDataToMetaFile(new DhSectionPos(chunkPos.detailLevel, chunkPos.x, chunkPos.z), chunkDataView); + chunkSectionPos = chunkSectionPos.convertNewToDetailLevel((byte) this.minDetailLevel); + this.writeChunkDataToMetaFile(chunkSectionPos, chunkDataView); } private void writeChunkDataToMetaFile(DhSectionPos sectionPos, ChunkSizedFullDataAccessor chunkData) { 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 3fa1cc495..56eaf760d 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 @@ -344,7 +344,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I { checkAndLogPhantomDataSourceLifeCycles(); - DhLodPos chunkLodPos = new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkAccessor.pos.x, chunkAccessor.pos.z); + DhLodPos chunkLodPos = new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkAccessor.chunkPos.x, chunkAccessor.chunkPos.z); LodUtil.assertTrue(this.pos.getSectionBBoxPos().overlapsExactly(chunkLodPos), "Chunk pos " + chunkLodPos + " doesn't exactly overlap with section " + this.pos); //LOGGER.info("Write Chunk {} to file {}", chunkPos, pos); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/GeneratedFullDataFileHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/GeneratedFullDataFileHandler.java index c2326c3cf..cfa5c3a7e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/GeneratedFullDataFileHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/file/fullDatafile/GeneratedFullDataFileHandler.java @@ -349,7 +349,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler return (chunkSizedFullDataSource) -> { - if (chunkSizedFullDataSource.getLodPos().overlapsExactly(this.loadedTargetFullDataSource.getSectionPos().getSectionBBoxPos())) + if (chunkSizedFullDataSource.getSectionPos().overlapsExactly(this.loadedTargetFullDataSource.getSectionPos())) { ((DhLevel) level).saveWrites(chunkSizedFullDataSource); //GeneratedFullDataFileHandler.this.write(this.loadedTargetFullDataSource.getSectionPos(), chunkSizedFullDataSource); 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 4c4cef87b..3d4de5638 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 @@ -30,7 +30,6 @@ import com.seibel.distanthorizons.core.file.metaData.AbstractMetaDataContainerFi import com.seibel.distanthorizons.core.file.metaData.BaseMetaData; import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.render.renderer.DebugRenderer; -import com.seibel.distanthorizons.core.pos.DhLodPos; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderLoader; import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderSource; @@ -136,8 +135,8 @@ public class RenderDataMetaFile extends AbstractMetaDataContainerFile implements public void updateChunkIfSourceExistsAsync(ChunkSizedFullDataAccessor chunkDataView) { - DhLodPos chunkPos = chunkDataView.getLodPos(); - LodUtil.assertTrue(this.pos.getSectionBBoxPos().overlapsExactly(chunkPos), "Chunk pos " + chunkPos + " doesn't overlap with section " + this.pos); + DhSectionPos chunkSectionPos = chunkDataView.getSectionPos(); + LodUtil.assertTrue(this.pos.overlapsExactly(chunkSectionPos), "Chunk pos " + chunkSectionPos + " doesn't overlap with section " + this.pos); // update the render source if one exists CompletableFuture renderSourceLoadFuture = this.getCachedDataSourceAsync(false); @@ -156,7 +155,7 @@ public class RenderDataMetaFile extends AbstractMetaDataContainerFile implements Color debugColor = dataUpdated ? Color.blue : Color.red; DebugRenderer.makeParticle( new DebugRenderer.BoxParticle( - new DebugRenderer.Box(chunkDataView.getLodPos(), 32f, 64f + offset, 0.07f, debugColor), + new DebugRenderer.Box(chunkDataView.getSectionPos(), 32f, 64f + offset, 0.07f, debugColor), 2.0, 16f ) ); 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 db67a2ca4..0b5f4bb4c 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 @@ -253,16 +253,18 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider } private void writeChunkDataToFileRecursively(ChunkSizedFullDataAccessor chunk, byte sectionDetailLevel) { - DhLodPos boundingPos = chunk.getLodPos(); - DhLodPos minSectionPos = boundingPos.convertToDetailLevel(sectionDetailLevel); + DhSectionPos boundingPos = chunk.getSectionPos(); + DhSectionPos minSectionPos = boundingPos.convertNewToDetailLevel(sectionDetailLevel); - int width = (sectionDetailLevel > boundingPos.detailLevel) ? 1 : boundingPos.getWidthAtDetail(sectionDetailLevel); + DhSectionPos fileSectionPos = new DhSectionPos((byte)0, 0, 0); + + int width = (sectionDetailLevel > boundingPos.sectionDetailLevel) ? 1 : boundingPos.getWidthCountForLowerDetailedSection(sectionDetailLevel); for (int xOffset = 0; xOffset < width; xOffset++) { for (int zOffset = 0; zOffset < width; zOffset++) { - DhSectionPos sectionPos = new DhSectionPos(sectionDetailLevel, minSectionPos.x + xOffset, minSectionPos.z + zOffset); - RenderDataMetaFile metaFile = this.metaFileBySectionPos.get(sectionPos); // bypass the getLoadOrMakeFile() since we only want cached files. + fileSectionPos.mutate(sectionDetailLevel, minSectionPos.sectionX + xOffset, minSectionPos.sectionZ + zOffset); + RenderDataMetaFile metaFile = this.metaFileBySectionPos.get(fileSectionPos); // bypass the getLoadOrMakeFile() since we only want cached files. if (metaFile != null) { metaFile.updateChunkIfSourceExistsAsync(chunk); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java index ac3ec177c..a75d24755 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/ClientLevelModule.java @@ -175,16 +175,16 @@ public class ClientLevelModule implements Closeable //===============// public void writeChunkDataToFile(ChunkSizedFullDataAccessor data) { - DhLodPos pos = data.getLodPos().convertToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET); + DhSectionPos pos = data.getSectionPos().convertNewToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET); ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); if (ClientRenderState != null) { - ClientRenderState.renderSourceFileHandler.writeChunkDataToFile(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data); + ClientRenderState.renderSourceFileHandler.writeChunkDataToFile(pos, data); } else { - this.parentClientLevel.getFileHandler().writeChunkDataToFile(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data); + this.parentClientLevel.getFileHandler().writeChunkDataToFile(pos, data); } } 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 2bee0ac1c..2fa741570 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 @@ -58,8 +58,9 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel @Override public void saveWrites(ChunkSizedFullDataAccessor data) { - DhLodPos pos = data.getLodPos().convertToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET); - getFileHandler().writeChunkDataToFile(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data); + DhSectionPos pos = data.getSectionPos(); + pos.convertSelfToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET); + this.getFileHandler().writeChunkDataToFile(pos, data); } @Override 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 bc2b38426..76cfdb4c3 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 @@ -192,11 +192,14 @@ public class DhLodPos implements Comparable public boolean overlapsExactly(DhLodPos other) { if (this.equals(other)) + { return true; - if (this.detailLevel == other.detailLevel) + } + else if (this.detailLevel == other.detailLevel) + { return false; - - if (this.detailLevel > other.detailLevel) + } + else if (this.detailLevel > other.detailLevel) { return this.equals(other.convertToDetailLevel(this.detailLevel)); } 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 77e2646a1..44d4019b4 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 @@ -106,6 +106,18 @@ 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) { @@ -256,7 +268,26 @@ public class DhSectionPos // comparisons // //=============// - public boolean overlaps(DhSectionPos other) { return this.getSectionBBoxPos().overlapsExactly(other.getSectionBBoxPos()); } + public boolean overlapsExactly(DhSectionPos other) + { + // original logic from DhLodPos + if (this.equals(other)) + { + return true; + } + else if (this.sectionDetailLevel == other.sectionDetailLevel) + { + return false; + } + else if (this.sectionDetailLevel > other.sectionDetailLevel) + { + return this.equals(other.convertNewToDetailLevel(this.sectionDetailLevel)); + } + else + { + return other.equals(this.convertNewToDetailLevel(other.sectionDetailLevel)); + } + } public boolean contains(DhSectionPos otherPos) { 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 c372fd203..e40f4f2ab 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 @@ -404,6 +404,7 @@ public class QuadTree { if (node != null || includeNullNodes) { + // TODO can these DhSectionPos be pooled? DhSectionPos rootPos = new DhSectionPos(QuadTree.this.treeMinDetailLevel, pos2D.x, pos2D.y); if (QuadTree.this.isSectionPosInBounds(rootPos)) {