From e1c0299368d91be48a398513dc45fed4ac36ae32 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sun, 23 Apr 2023 14:50:38 -0500 Subject: [PATCH] refactor and document FullData sample methods --- .../accessor/FullDataArrayAccessor.java | 12 ++- .../fullData/accessor/IFullDataAccessor.java | 1 - .../accessor/SingleFullDataAccessor.java | 15 +++- .../sources/CompleteFullDataSource.java | 56 +++++++----- .../fullData/sources/IFullDataSource.java | 1 - .../sources/IIncompleteFullDataSource.java | 5 ++ .../sources/SparseFullDataSource.java | 68 ++++++++------- .../sources/SpottyFullDataSource.java | 85 +++++++++++-------- .../fullDatafile/FullDataFileHandler.java | 8 +- .../SubDimensionLevelMatcher.java | 2 +- 10 files changed, 150 insertions(+), 103 deletions(-) diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullDataArrayAccessor.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullDataArrayAccessor.java index 53511186c..6da057347 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullDataArrayAccessor.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullDataArrayAccessor.java @@ -111,17 +111,21 @@ public class FullDataArrayAccessor implements IFullDataAccessor } } - public void downsampleFrom(FullDataArrayAccessor arrayView) + /** + * Takes a higher detail {@link FullDataArrayAccessor}'s to a lower detail. + * @param fullDataAccessor must be larger than this {@link FullDataArrayAccessor} and its width must a power of two + */ + public void downsampleFrom(FullDataArrayAccessor fullDataAccessor) { - LodUtil.assertTrue(arrayView.width > this.width && arrayView.width % this.width == 0); + LodUtil.assertTrue(fullDataAccessor.width > this.width && fullDataAccessor.width % this.width == 0); - int dataPerUnit = arrayView.width / this.width; + int dataPointsPerWidthUnit = fullDataAccessor.width / this.width; for (int xOffset = 0; xOffset < this.width; xOffset++) { for (int zOffset = 0; zOffset < this.width; zOffset++) { SingleFullDataAccessor column = this.get(xOffset, zOffset); - column.downsampleFrom(arrayView.subView(dataPerUnit, xOffset * dataPerUnit, zOffset * dataPerUnit)); + column.downsampleFrom(fullDataAccessor.subView(dataPointsPerWidthUnit, xOffset * dataPointsPerWidthUnit, zOffset * dataPointsPerWidthUnit)); } } } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/IFullDataAccessor.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/IFullDataAccessor.java index acb5a3919..cad84191e 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/IFullDataAccessor.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/IFullDataAccessor.java @@ -3,7 +3,6 @@ package com.seibel.lod.core.dataObjects.fullData.accessor; import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; -import com.seibel.lod.core.dataObjects.render.ColumnRenderSource; import com.seibel.lod.core.util.FullDataPointUtil; import java.util.Iterator; diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/SingleFullDataAccessor.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/SingleFullDataAccessor.java index 553975ea0..edf778d30 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/SingleFullDataAccessor.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/SingleFullDataAccessor.java @@ -4,7 +4,9 @@ import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; import com.seibel.lod.core.util.FullDataPointUtil; /** + * Represents a single column of Full LOD data. * + * @see FullDataPointUtil */ public class SingleFullDataAccessor implements IFullDataAccessor { @@ -56,10 +58,11 @@ public class SingleFullDataAccessor implements IFullDataAccessor return this; } + /** @return the entire array of raw full data points. */ public long[] getRaw() { return this.dataArrays[this.dataArrayIndex]; } public long getSingle(int yIndex) { return this.dataArrays[this.dataArrayIndex][yIndex]; } - public void setSingle(int yIndex, long value) { this.dataArrays[this.dataArrayIndex][yIndex] = value; } + public void setSingle(int yIndex, long fullDataPoint) { this.dataArrays[this.dataArrayIndex][yIndex] = fullDataPoint; } public void setNew(long[] newArray) { this.dataArrays[this.dataArrayIndex] = newArray; } @@ -80,7 +83,7 @@ public class SingleFullDataAccessor implements IFullDataAccessor return this; } - /** WARNING: It may potentially share the underlying array object! */ + /** WARNING: This may potentially share the underlying array objects! */ public void shadowCopyTo(SingleFullDataAccessor target) { if (target.mapping.equals(this.mapping)) @@ -92,6 +95,7 @@ public class SingleFullDataAccessor implements IFullDataAccessor int[] remappedEntryIds = target.mapping.mergeAndReturnRemappedEntityIds(this.mapping); long[] sourceData = this.dataArrays[this.dataArrayIndex]; long[] newData = new long[sourceData.length]; + for (int i = 0; i < newData.length; i++) { newData[i] = FullDataPointUtil.remap(remappedEntryIds, sourceData[i]); @@ -100,6 +104,7 @@ public class SingleFullDataAccessor implements IFullDataAccessor } } + /** Copies both ID data and mapping data. */ public void deepCopyTo(SingleFullDataAccessor target) { if (target.mapping.equals(this.mapping)) @@ -119,9 +124,13 @@ public class SingleFullDataAccessor implements IFullDataAccessor } } + /** + * Replaces this column's data with data from the input {@link IFullDataAccessor}.
+ * This is used to convert higher detail LOD data to lower detail LOD data. + */ public void downsampleFrom(IFullDataAccessor source) { - //TODO: Temp downsample method + //TODO: average the data instead of just picking the first column SingleFullDataAccessor firstColumn = source.get(0); firstColumn.deepCopyTo(this); } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/CompleteFullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/CompleteFullDataSource.java index cf41e0b81..dbf58273d 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/CompleteFullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/CompleteFullDataSource.java @@ -24,7 +24,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu { private static final Logger LOGGER = DhLoggerBuilder.getLogger(); public static final byte SECTION_SIZE_OFFSET = DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL; - public static final int SECTION_SIZE = 1 << SECTION_SIZE_OFFSET; + public static final int SECTION_SIZE = BitShiftUtil.powerOfTwo(SECTION_SIZE_OFFSET); public static final byte LATEST_VERSION = 0; public static final long TYPE_ID = "CompleteFullDataSource".hashCode(); @@ -33,8 +33,9 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu - // TODO why is this protected? - protected CompleteFullDataSource(DhSectionPos sectionPos) + + public static CompleteFullDataSource createEmpty(DhSectionPos pos) { return new CompleteFullDataSource(pos); } + private CompleteFullDataSource(DhSectionPos sectionPos) { super(new FullDataPointIdMap(), new long[SECTION_SIZE*SECTION_SIZE][0], SECTION_SIZE); this.sectionPos = sectionPos; @@ -44,6 +45,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu { super(mapping, data, SECTION_SIZE); LodUtil.assertTrue(data.length == SECTION_SIZE * SECTION_SIZE); + this.sectionPos = pos; this.isEmpty = false; } @@ -69,17 +71,20 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu public void update(ChunkSizedFullDataAccessor chunkDataView) { LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(chunkDataView.getLodPos())); - if (this.getDataDetailLevel() == 0) + if (this.getDataDetailLevel() == LodUtil.BLOCK_DETAIL_LEVEL) { - DhBlockPos2D chunkBlockPos = new DhBlockPos2D(chunkDataView.pos.x * 16, chunkDataView.pos.z * 16); + DhBlockPos2D chunkBlockPos = new DhBlockPos2D(chunkDataView.pos.x * LodUtil.CHUNK_WIDTH, chunkDataView.pos.z * LodUtil.CHUNK_WIDTH); DhBlockPos2D blockOffset = chunkBlockPos.subtract(this.sectionPos.getCorner().getCornerBlockPos()); LodUtil.assertTrue(blockOffset.x >= 0 && blockOffset.x < SECTION_SIZE && blockOffset.z >= 0 && blockOffset.z < SECTION_SIZE); this.isEmpty = false; - chunkDataView.shadowCopyTo(this.subView(16, blockOffset.x, blockOffset.z)); - { // DEBUG ASSERTION - for (int x = 0; x < 16; x++) + + chunkDataView.shadowCopyTo(this.subView(LodUtil.CHUNK_WIDTH, blockOffset.x, blockOffset.z)); + + // DEBUG ASSERTION + { + for (int x = 0; x < LodUtil.CHUNK_WIDTH; x++) { - for (int z = 0; z < 16; z++) + for (int z = 0; z < LodUtil.CHUNK_WIDTH; z++) { SingleFullDataAccessor column = this.get(x + blockOffset.x, z + blockOffset.z); LodUtil.assertTrue(column.doesColumnExist()); @@ -87,29 +92,31 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu } } } - else if (this.getDataDetailLevel() < 4) + else if (this.getDataDetailLevel() < LodUtil.CHUNK_DETAIL_LEVEL) { int dataPerFull = 1 << this.getDataDetailLevel(); - int fullSize = 16 / dataPerFull; + int fullSize = LodUtil.CHUNK_WIDTH / dataPerFull; DhLodPos dataOffset = chunkDataView.getLodPos().getCornerLodPos(this.getDataDetailLevel()); DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetailLevel()); + int offsetX = dataOffset.x - baseOffset.x; int offsetZ = dataOffset.z - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); + this.isEmpty = false; - for (int ox = 0; ox < fullSize; ox++) + for (int xOffset = 0; xOffset < fullSize; xOffset++) { - for (int oz = 0; oz < fullSize; oz++) + for (int zOffset = 0; zOffset < fullSize; zOffset++) { - SingleFullDataAccessor column = this.get(ox + offsetX, oz + offsetZ); - column.downsampleFrom(chunkDataView.subView(dataPerFull, ox * dataPerFull, oz * dataPerFull)); + SingleFullDataAccessor column = this.get(xOffset + offsetX, zOffset + offsetZ); + column.downsampleFrom(chunkDataView.subView(dataPerFull, xOffset * dataPerFull, zOffset * dataPerFull)); } } } - else if (this.getDataDetailLevel() >= 4) + else if (this.getDataDetailLevel() >= LodUtil.CHUNK_DETAIL_LEVEL) { //FIXME: TEMPORARY - int chunkPerFull = 1 << (this.getDataDetailLevel() - 4); + int chunkPerFull = 1 << (this.getDataDetailLevel() - LodUtil.CHUNK_DETAIL_LEVEL); if (chunkDataView.pos.x % chunkPerFull != 0 || chunkDataView.pos.z % chunkPerFull != 0) { return; @@ -117,9 +124,11 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetailLevel()); DhLodPos dataOffset = chunkDataView.getLodPos().convertToDetailLevel(this.getDataDetailLevel()); + int offsetX = dataOffset.x - baseOffset.x; int offsetZ = dataOffset.z - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); + this.isEmpty = false; chunkDataView.get(0, 0).deepCopyTo(this.get(offsetX, offsetZ)); } @@ -265,8 +274,6 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu } - public static CompleteFullDataSource createEmpty(DhSectionPos pos) { return new CompleteFullDataSource(pos); } - /** Returns whether data at the given posToWrite can effect the target region file at posToTest. */ public static boolean firstDataPosCanAffectSecond(DhSectionPos posToWrite, DhSectionPos posToTest) { @@ -304,7 +311,10 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu LodUtil.assertTrue(this.sectionPos.overlaps(subData.sectionPos)); LodUtil.assertTrue(subData.sectionPos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); if (!firstDataPosCanAffectSecond(this.sectionPos, subData.sectionPos)) + { return; + } + DhSectionPos lowerSectPos = subData.sectionPos; byte detailDiff = (byte) (this.sectionPos.sectionDetailLevel - subData.sectionPos.sectionDetailLevel); byte targetDataDetail = this.getDataDetailLevel(); @@ -318,12 +328,12 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu int dataOffsetZ = subDataPos.z - minDataPos.z; LodUtil.assertTrue(dataOffsetX >= 0 && dataOffsetX < SECTION_SIZE && dataOffsetZ >= 0 && dataOffsetZ < SECTION_SIZE); - for (int ox = 0; ox < count; ox++) + for (int xOffset = 0; xOffset < count; xOffset++) { - for (int oz = 0; oz < count; oz++) + for (int zOffset = 0; zOffset < count; zOffset++) { - SingleFullDataAccessor column = this.get(ox + dataOffsetX, oz + dataOffsetZ); - column.downsampleFrom(subData.subView(dataPerCount, ox * dataPerCount, oz * dataPerCount)); + SingleFullDataAccessor column = this.get(xOffset + dataOffsetX, zOffset + dataOffsetZ); + column.downsampleFrom(subData.subView(dataPerCount, xOffset * dataPerCount, zOffset * dataPerCount)); } } } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IFullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IFullDataSource.java index 9daaca418..93b3fe1bb 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IFullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IFullDataSource.java @@ -9,7 +9,6 @@ import com.seibel.lod.core.dataObjects.render.ColumnRenderSource; import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile; import com.seibel.lod.core.level.IDhLevel; import com.seibel.lod.core.pos.DhSectionPos; -import com.seibel.lod.core.util.FullDataPointUtil; import java.io.BufferedOutputStream; import java.io.IOException; diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IIncompleteFullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IIncompleteFullDataSource.java index 071752fa2..bf1ae3490 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IIncompleteFullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IIncompleteFullDataSource.java @@ -2,6 +2,11 @@ package com.seibel.lod.core.dataObjects.fullData.sources; public interface IIncompleteFullDataSource extends IFullDataSource { + /** + * Overwrites data in this object with non-null data from the input {@link IFullDataSource}. + * + * This can be used to either merge same sized data sources or + */ void sampleFrom(IFullDataSource fullDataSource); /** diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SparseFullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SparseFullDataSource.java index 7076399e6..4012564f5 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SparseFullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SparseFullDataSource.java @@ -25,7 +25,8 @@ import java.util.BitSet; public class SparseFullDataSource implements IIncompleteFullDataSource { private static final Logger LOGGER = DhLoggerBuilder.getLogger(); - public static final byte SPARSE_UNIT_DETAIL = 4; + + public static final byte SPARSE_UNIT_DETAIL = LodUtil.CHUNK_DETAIL_LEVEL; public static final byte SPARSE_UNIT_SIZE = (byte) BitShiftUtil.powerOfTwo(SPARSE_UNIT_DETAIL); public static final byte SECTION_SIZE_OFFSET = 6; @@ -62,9 +63,11 @@ public class SparseFullDataSource implements IIncompleteFullDataSource { LodUtil.assertTrue(sectionPos.sectionDetailLevel > SPARSE_UNIT_DETAIL); LodUtil.assertTrue(sectionPos.sectionDetailLevel <= MAX_SECTION_DETAIL); + this.sectionPos = sectionPos; this.chunks = 1 << (byte) (sectionPos.sectionDetailLevel - SPARSE_UNIT_DETAIL); this.dataPerChunk = SECTION_SIZE / this.chunks; + this.sparseData = new FullDataArrayAccessor[this.chunks * this.chunks]; this.chunkPos = sectionPos.getCorner(SPARSE_UNIT_DETAIL); this.mapping = new FullDataPointIdMap(); @@ -74,9 +77,11 @@ public class SparseFullDataSource implements IIncompleteFullDataSource { LodUtil.assertTrue(sectionPos.sectionDetailLevel > SPARSE_UNIT_DETAIL); LodUtil.assertTrue(sectionPos.sectionDetailLevel <= MAX_SECTION_DETAIL); + this.sectionPos = sectionPos; this.chunks = 1 << (byte) (sectionPos.sectionDetailLevel - SPARSE_UNIT_DETAIL); this.dataPerChunk = SECTION_SIZE / this.chunks; + LodUtil.assertTrue(this.chunks * this.chunks == data.length); this.sparseData = data; this.chunkPos = sectionPos.getCorner(SPARSE_UNIT_DETAIL); @@ -147,78 +152,81 @@ public class SparseFullDataSource implements IIncompleteFullDataSource @Override - public void sampleFrom(IFullDataSource source) + public void sampleFrom(IFullDataSource fullDataSource) { - DhSectionPos pos = source.getSectionPos(); + DhSectionPos pos = fullDataSource.getSectionPos(); LodUtil.assertTrue(pos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); LodUtil.assertTrue(pos.overlaps(this.sectionPos)); - if (source.isEmpty()) + if (fullDataSource.isEmpty()) { return; } - if (source instanceof SparseFullDataSource) + if (fullDataSource instanceof SparseFullDataSource) { - this.sampleFrom((SparseFullDataSource) source); + this.sampleFrom((SparseFullDataSource) fullDataSource); } - else if (source instanceof CompleteFullDataSource) + else if (fullDataSource instanceof CompleteFullDataSource) { - this.sampleFrom((CompleteFullDataSource) source); + this.sampleFrom((CompleteFullDataSource) fullDataSource); } else { - LodUtil.assertNotReach(); + LodUtil.assertNotReach("SampleFrom not implemented for ["+IFullDataSource.class.getSimpleName()+"] with class ["+fullDataSource.getClass().getSimpleName()+"]."); } } - - private void sampleFrom(SparseFullDataSource sparseSource) + + private void sampleFrom(SparseFullDataSource sparseDataSource) { - DhSectionPos pos = sparseSource.getSectionPos(); + DhSectionPos pos = sparseDataSource.getSectionPos(); this.isEmpty = false; DhLodPos basePos = this.sectionPos.getCorner(SPARSE_UNIT_DETAIL); DhLodPos dataPos = pos.getCorner(SPARSE_UNIT_DETAIL); + int offsetX = dataPos.x-basePos.x; int offsetZ = dataPos.z-basePos.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < this.chunks && offsetZ >= 0 && offsetZ < this.chunks); - for (int xOffset = 0; xOffset < sparseSource.chunks; xOffset++) + for (int xOffset = 0; xOffset < sparseDataSource.chunks; xOffset++) { - for (int zOffset = 0; zOffset < sparseSource.chunks; zOffset++) + for (int zOffset = 0; zOffset < sparseDataSource.chunks; zOffset++) { - FullDataArrayAccessor sourceChunk = sparseSource.sparseData[xOffset * sparseSource.chunks + zOffset]; + FullDataArrayAccessor sourceChunk = sparseDataSource.sparseData[xOffset * sparseDataSource.chunks + zOffset]; if (sourceChunk != null) { - FullDataArrayAccessor buff = new FullDataArrayAccessor(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); - buff.downsampleFrom(sourceChunk); - this.sparseData[(xOffset + offsetX) * this.chunks + (zOffset + offsetZ)] = buff; + FullDataArrayAccessor newFullDataAccessor = new FullDataArrayAccessor(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); + newFullDataAccessor.downsampleFrom(sourceChunk); + this.sparseData[(xOffset + offsetX) * this.chunks + (zOffset + offsetZ)] = newFullDataAccessor; } } } } - private void sampleFrom(CompleteFullDataSource fullSource) + private void sampleFrom(CompleteFullDataSource completeDataSource) { - DhSectionPos pos = fullSource.getSectionPos(); + DhSectionPos pos = completeDataSource.getSectionPos(); this.isEmpty = false; DhLodPos basePos = this.sectionPos.getCorner(SPARSE_UNIT_DETAIL); DhLodPos dataPos = pos.getCorner(SPARSE_UNIT_DETAIL); - int coveredChunks = pos.getWidth(SPARSE_UNIT_DETAIL).numberOfLodSectionsWide; - int sourceDataPerChunk = SPARSE_UNIT_SIZE >>> fullSource.getDataDetailLevel(); - LodUtil.assertTrue(coveredChunks*sourceDataPerChunk == CompleteFullDataSource.SECTION_SIZE); - int offsetX = dataPos.x-basePos.x; - int offsetZ = dataPos.z-basePos.z; - LodUtil.assertTrue(offsetX >=0 && offsetX < this.chunks && offsetZ >=0 && offsetZ < this.chunks); + + int coveredChunks = pos.getWidth(SPARSE_UNIT_DETAIL).numberOfLodSectionsWide; + int sourceDataPerChunk = SPARSE_UNIT_SIZE >>> completeDataSource.getDataDetailLevel(); + LodUtil.assertTrue((coveredChunks * sourceDataPerChunk) == CompleteFullDataSource.SECTION_SIZE); + + int xDataOffset = dataPos.x - basePos.x; + int zDataOffset = dataPos.z - basePos.z; + LodUtil.assertTrue(xDataOffset >= 0 && xDataOffset < this.chunks && zDataOffset >= 0 && zDataOffset < this.chunks); for (int xOffset = 0; xOffset < coveredChunks; xOffset++) { for (int zOffset = 0; zOffset < coveredChunks; zOffset++) { - FullDataArrayAccessor sourceChunk = fullSource.subView(sourceDataPerChunk, xOffset * sourceDataPerChunk, zOffset * sourceDataPerChunk); - FullDataArrayAccessor buff = new FullDataArrayAccessor(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); - buff.downsampleFrom(sourceChunk); - this.sparseData[(xOffset + offsetX) * this.chunks + (zOffset + offsetZ)] = buff; + FullDataArrayAccessor sourceChunk = completeDataSource.subView(sourceDataPerChunk, xOffset * sourceDataPerChunk, zOffset * sourceDataPerChunk); + FullDataArrayAccessor newFullDataAccessor = new FullDataArrayAccessor(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); + newFullDataAccessor.downsampleFrom(sourceChunk); + this.sparseData[(xOffset + xDataOffset) * this.chunks + (zOffset + zDataOffset)] = newFullDataAccessor; } } } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SpottyFullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SpottyFullDataSource.java index fe1f469e7..d2b049b5f 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SpottyFullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SpottyFullDataSource.java @@ -40,7 +40,8 @@ public class SpottyFullDataSource extends FullDataArrayAccessor implements IInco // constructors // //==============// - protected SpottyFullDataSource(DhSectionPos sectionPos) + public static SpottyFullDataSource createEmpty(DhSectionPos pos) { return new SpottyFullDataSource(pos); } + private SpottyFullDataSource(DhSectionPos sectionPos) { super(new FullDataPointIdMap(), new long[SECTION_SIZE*SECTION_SIZE][0], SECTION_SIZE); LodUtil.assertTrue(sectionPos.sectionDetailLevel > SparseFullDataSource.MAX_SECTION_DETAIL); @@ -57,12 +58,10 @@ public class SpottyFullDataSource extends FullDataArrayAccessor implements IInco this.sectionPos = pos; this.isColumnNotEmpty = isColumnNotEmpty; - this.worldGenStep = EDhApiWorldGenerationStep.EMPTY; + this.worldGenStep = worldGenStep; this.isEmpty = false; } - public static SpottyFullDataSource createEmpty(DhSectionPos pos) { return new SpottyFullDataSource(pos); } - //===============// @@ -248,41 +247,48 @@ public class SpottyFullDataSource extends FullDataArrayAccessor implements IInco } @Override - public void sampleFrom(IFullDataSource source) + public void sampleFrom(IFullDataSource fullDataSource) { - DhSectionPos pos = source.getSectionPos(); + DhSectionPos pos = fullDataSource.getSectionPos(); LodUtil.assertTrue(pos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); LodUtil.assertTrue(pos.overlaps(this.sectionPos)); - if (source.isEmpty()) - return; - if (source instanceof SparseFullDataSource) + if (fullDataSource.isEmpty()) { - this.sampleFrom((SparseFullDataSource) source); + return; + } + + + if (fullDataSource instanceof SparseFullDataSource) + { + this.sampleFrom((SparseFullDataSource) fullDataSource); } - else if (source instanceof CompleteFullDataSource) + else if (fullDataSource instanceof CompleteFullDataSource) { - this.sampleFrom((CompleteFullDataSource) source); + this.sampleFrom((CompleteFullDataSource) fullDataSource); } else { - LodUtil.assertNotReach(); + LodUtil.assertNotReach("SampleFrom not implemented for ["+IFullDataSource.class.getSimpleName()+"] with class ["+fullDataSource.getClass().getSimpleName()+"]."); } } private void sampleFrom(SparseFullDataSource sparseSource) { + DhLodPos thisLodPos = this.sectionPos.getCorner(this.getDataDetailLevel()); DhSectionPos pos = sparseSource.getSectionPos(); + this.isEmpty = false; - + if (this.getDataDetailLevel() > this.sectionPos.sectionDetailLevel) { - DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel()); - DhLodPos dataPos = pos.getCorner(this.getDataDetailLevel()); - int offsetX = dataPos.x - basePos.x; - int offsetZ = dataPos.z - basePos.z; + DhLodPos dataLodPos = pos.getCorner(this.getDataDetailLevel()); + + int offsetX = dataLodPos.x - thisLodPos.x; + int offsetZ = dataLodPos.z - thisLodPos.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); - int chunksPerData = 1 << (this.getDataDetailLevel() - SparseFullDataSource.SPARSE_UNIT_DETAIL); + + int chunksPerData = 1 << (this.getDataDetailLevel() - SparseFullDataSource.SPARSE_UNIT_DETAIL); int dataSpan = this.sectionPos.getWidth(this.getDataDetailLevel()).numberOfLodSectionsWide; for (int xOffset = 0; xOffset < dataSpan; xOffset++) @@ -303,16 +309,21 @@ public class SpottyFullDataSource extends FullDataArrayAccessor implements IInco } else { - DhLodPos dataPos = pos.getSectionBBoxPos(); - int lowerSectionsPerData = this.sectionPos.getWidth(dataPos.detailLevel).numberOfLodSectionsWide; - if (dataPos.x % lowerSectionsPerData != 0 || dataPos.z % lowerSectionsPerData != 0) return; - - DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel()); - dataPos = dataPos.convertToDetailLevel(this.getDataDetailLevel()); - int offsetX = dataPos.x - basePos.x; - int offsetZ = dataPos.z - basePos.z; - SingleFullDataAccessor column = sparseSource.tryGet(0, 0); - if (column != null) { + DhLodPos dataLodPos = pos.getSectionBBoxPos(); + int lowerSectionsPerData = this.sectionPos.getWidth(dataLodPos.detailLevel).numberOfLodSectionsWide; + if (dataLodPos.x % lowerSectionsPerData != 0 || dataLodPos.z % lowerSectionsPerData != 0) + { + return; + } + + + dataLodPos = dataLodPos.convertToDetailLevel(this.getDataDetailLevel()); + int offsetX = dataLodPos.x - thisLodPos.x; + int offsetZ = dataLodPos.z - thisLodPos.z; + + SingleFullDataAccessor column = sparseSource.tryGet(0, 0); + if (column != null) + { column.deepCopyTo(this.get(offsetX, offsetZ)); this.isColumnNotEmpty.set(offsetX * SECTION_SIZE + offsetZ, true); } @@ -327,15 +338,16 @@ public class SpottyFullDataSource extends FullDataArrayAccessor implements IInco if (this.getDataDetailLevel() > this.sectionPos.sectionDetailLevel) { - DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel()); - DhLodPos dataPos = pos.getCorner(this.getDataDetailLevel()); - int offsetX = dataPos.x - basePos.x; - int offsetZ = dataPos.z - basePos.z; - int dataSpan = this.sectionPos.getWidth(this.getDataDetailLevel()).numberOfLodSectionsWide; + DhLodPos thisLodPos = this.sectionPos.getCorner(this.getDataDetailLevel()); + DhLodPos dataLodPos = pos.getCorner(this.getDataDetailLevel()); - for (int xOffset = 0; xOffset < dataSpan; xOffset++) + int offsetX = dataLodPos.x - thisLodPos.x; + int offsetZ = dataLodPos.z - thisLodPos.z; + int dataWidth = this.sectionPos.getWidth(this.getDataDetailLevel()).numberOfLodSectionsWide; + + for (int xOffset = 0; xOffset < dataWidth; xOffset++) { - for (int zOffset = 0; zOffset < dataSpan; zOffset++) + for (int zOffset = 0; zOffset < dataWidth; zOffset++) { this.isColumnNotEmpty.set((offsetX + xOffset) * SECTION_SIZE + offsetZ + zOffset, true); } @@ -350,6 +362,7 @@ public class SpottyFullDataSource extends FullDataArrayAccessor implements IInco return; } + DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel()); dataPos = dataPos.convertToDetailLevel(this.getDataDetailLevel()); int offsetX = dataPos.x - basePos.x; diff --git a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java index f16aa27ce..d566ac422 100644 --- a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java +++ b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java @@ -357,8 +357,8 @@ public class FullDataFileHandler implements IFullDataSourceProvider } } final ArrayList> futures = new ArrayList<>(existFiles.size()); - final IIncompleteFullDataSource dataSource = pos.sectionDetailLevel <= SparseFullDataSource.MAX_SECTION_DETAIL ? - SparseFullDataSource.createEmpty(pos) : + final IIncompleteFullDataSource incompleteFullDataSource = pos.sectionDetailLevel <= SparseFullDataSource.MAX_SECTION_DETAIL ? + SparseFullDataSource.createEmpty(pos) : SpottyFullDataSource.createEmpty(pos); for (FullDataMetaFile metaFile : existFiles) @@ -369,7 +369,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider if (data != null) { //LOGGER.info("Merging data from {} into {}", data.getSectionPos(), pos); - dataSource.sampleFrom(data); + incompleteFullDataSource.sampleFrom(data); } }) .exceptionally((e) -> @@ -380,7 +380,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider ); } return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) - .thenApply((v) -> dataSource.tryPromotingToCompleteDataSource()); + .thenApply((v) -> incompleteFullDataSource.tryPromotingToCompleteDataSource()); } } diff --git a/core/src/main/java/com/seibel/lod/core/file/subDimMatching/SubDimensionLevelMatcher.java b/core/src/main/java/com/seibel/lod/core/file/subDimMatching/SubDimensionLevelMatcher.java index 57f9af936..f8b7790db 100644 --- a/core/src/main/java/com/seibel/lod/core/file/subDimMatching/SubDimensionLevelMatcher.java +++ b/core/src/main/java/com/seibel/lod/core/file/subDimMatching/SubDimensionLevelMatcher.java @@ -1,10 +1,10 @@ package com.seibel.lod.core.file.subDimMatching; import com.seibel.lod.core.config.Config; +import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullDataAccessor; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataAccessor; import com.seibel.lod.core.util.FullDataPointUtil; -import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullDataAccessor; import com.seibel.lod.core.dataObjects.transformers.LodDataBuilder; import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.file.fullDatafile.FullDataFileHandler;