diff --git a/core/src/main/java/com/seibel/lod/core/datatype/full/FullDataPointIdMap.java b/core/src/main/java/com/seibel/lod/core/datatype/full/FullDataPointIdMap.java index c0af3691a..132cad059 100644 --- a/core/src/main/java/com/seibel/lod/core/datatype/full/FullDataPointIdMap.java +++ b/core/src/main/java/com/seibel/lod/core/datatype/full/FullDataPointIdMap.java @@ -13,7 +13,7 @@ import java.util.concurrent.ConcurrentHashMap; /** * WARNING: This is not THREAD-SAFE! *

- * Used to map a numerical ID to a Biome/BlockState pair. + * Used to map a numerical IDs to a Biome/BlockState pair. * * @author Leetom * @version 2022-10-2 @@ -25,19 +25,19 @@ public class FullDataPointIdMap - public IBiomeWrapper getBiomeWrapper(int id) { return entries.get(id).biome; } - public IBlockStateWrapper getBlockStateWrapper(int id) { return entries.get(id).blockState; } + public IBiomeWrapper getBiomeWrapper(int id) { return this.entries.get(id).biome; } + public IBlockStateWrapper getBlockStateWrapper(int id) { return this.entries.get(id).blockState; } /** * If an entry with the given values already exists nothing will * be added but the existing item's ID will still be returned. */ - public int addIfNotPresentAndGetId(IBiomeWrapper biome, IBlockStateWrapper blockState) { return addIfNotPresentAndGetId(new Entry(biome, blockState)); } + public int addIfNotPresentAndGetId(IBiomeWrapper biome, IBlockStateWrapper blockState) { return this.addIfNotPresentAndGetId(new Entry(biome, blockState)); } private int addIfNotPresentAndGetId(Entry biomeBlockStateEntry) { - return idMap.computeIfAbsent(biomeBlockStateEntry, (entry) -> { - int id = entries.size(); - entries.add(entry); + return this.idMap.computeIfAbsent(biomeBlockStateEntry, (entry) -> { + int id = this.entries.size(); + this.entries.add(entry); return id; }); } @@ -54,7 +54,7 @@ public class FullDataPointIdMap int[] remappedEntryIds = new int[entriesToMerge.size()]; for (int i = 0; i < entriesToMerge.size(); i++) { - remappedEntryIds[i] = addIfNotPresentAndGetId(entriesToMerge.get(i)); + remappedEntryIds[i] = this.addIfNotPresentAndGetId(entriesToMerge.get(i)); } return remappedEntryIds; } @@ -63,8 +63,8 @@ public class FullDataPointIdMap void serialize(OutputStream outputStream) throws IOException { DataOutputStream dataStream = new DataOutputStream(outputStream); // DO NOT CLOSE! It would close all related streams - dataStream.writeInt(entries.size()); - for (Entry entry : entries) + dataStream.writeInt(this.entries.size()); + for (Entry entry : this.entries) { dataStream.writeUTF(entry.serialize()); } @@ -119,7 +119,7 @@ public class FullDataPointIdMap @Override - public int hashCode() { return Objects.hash(biome, blockState); } + public int hashCode() { return Objects.hash(this.biome, this.blockState); } @Override public boolean equals(Object other) @@ -130,11 +130,11 @@ public class FullDataPointIdMap if (!(other instanceof Entry)) return false; - return ((Entry) other).biome.equals(biome) && ((Entry) other).blockState.equals(blockState); + return ((Entry) other).biome.equals(this.biome) && ((Entry) other).blockState.equals(this.blockState); } - public String serialize() { return biome.serialize() + " " + blockState.serialize(); } + public String serialize() { return this.biome.serialize() + " " + this.blockState.serialize(); } public static Entry deserialize(String str) throws IOException { diff --git a/core/src/main/java/com/seibel/lod/core/datatype/full/FullDataSource.java b/core/src/main/java/com/seibel/lod/core/datatype/full/FullDataSource.java index 3c4824a0b..7d9757460 100644 --- a/core/src/main/java/com/seibel/lod/core/datatype/full/FullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/datatype/full/FullDataSource.java @@ -38,9 +38,9 @@ public class FullDataSource extends FullArrayView implements ILodDataSource @Override - public DhSectionPos getSectionPos() { return sectionPos; } + public DhSectionPos getSectionPos() { return this.sectionPos; } @Override - public byte getDataDetail() { return (byte) (sectionPos.sectionDetail-SECTION_SIZE_OFFSET); } + public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetail-SECTION_SIZE_OFFSET); } @Override public byte getDataVersion() { return LATEST_VERSION; } @@ -48,13 +48,13 @@ public class FullDataSource extends FullArrayView implements ILodDataSource @Override public void update(ChunkSizedData data) { - LodUtil.assertTrue(sectionPos.getSectionBBoxPos().overlaps(data.getBBoxLodPos())); - if (data.dataDetail == 0 && getDataDetail() == 0) + LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlaps(data.getBBoxLodPos())); + if (data.dataDetail == 0 && this.getDataDetail() == 0) { DhBlockPos2D chunkBlockPos = new DhBlockPos2D(data.x * 16, data.z * 16); - DhBlockPos2D blockOffset = chunkBlockPos.subtract(sectionPos.getCorner().getCorner()); + DhBlockPos2D blockOffset = chunkBlockPos.subtract(this.sectionPos.getCorner().getCorner()); LodUtil.assertTrue(blockOffset.x >= 0 && blockOffset.x < SECTION_SIZE && blockOffset.z >= 0 && blockOffset.z < SECTION_SIZE); - isEmpty = false; + this.isEmpty = false; data.shadowCopyTo(this.subView(16, blockOffset.x, blockOffset.z)); { // DEBUG ASSERTION for (int x = 0; x < 16; x++) @@ -67,16 +67,16 @@ public class FullDataSource extends FullArrayView implements ILodDataSource } } } - else if (data.dataDetail == 0 && getDataDetail() < 4) + else if (data.dataDetail == 0 && this.getDataDetail() < 4) { - int dataPerFull = 1 << getDataDetail(); + int dataPerFull = 1 << this.getDataDetail(); int fullSize = 16 / dataPerFull; - DhLodPos dataOffset = data.getBBoxLodPos().getCorner(getDataDetail()); - DhLodPos baseOffset = sectionPos.getCorner(getDataDetail()); + DhLodPos dataOffset = data.getBBoxLodPos().getCorner(this.getDataDetail()); + DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail()); int offsetX = dataOffset.x - baseOffset.x; int offsetZ = dataOffset.z - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); - isEmpty = false; + this.isEmpty = false; for (int ox = 0; ox < fullSize; ox++) { for (int oz = 0; oz < fullSize; oz++) @@ -86,19 +86,19 @@ public class FullDataSource extends FullArrayView implements ILodDataSource } } } - else if (data.dataDetail == 0 && getDataDetail() >= 4) + else if (data.dataDetail == 0 && this.getDataDetail() >= 4) { //FIXME: TEMPORARY - int chunkPerFull = 1 << (getDataDetail() - 4); + int chunkPerFull = 1 << (this.getDataDetail() - 4); if (data.x % chunkPerFull != 0 || data.z % chunkPerFull != 0) return; - DhLodPos baseOffset = sectionPos.getCorner(getDataDetail()); - DhLodPos dataOffset = data.getBBoxLodPos().convertUpwardsTo(getDataDetail()); + DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail()); + DhLodPos dataOffset = data.getBBoxLodPos().convertUpwardsTo(this.getDataDetail()); int offsetX = dataOffset.x - baseOffset.x; int offsetZ = dataOffset.z - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); - isEmpty = false; - data.get(0, 0).deepCopyTo(get(offsetX, offsetZ)); + this.isEmpty = false; + data.get(0, 0).deepCopyTo(this.get(offsetX, offsetZ)); } else { @@ -109,38 +109,38 @@ public class FullDataSource extends FullArrayView implements ILodDataSource } @Override - public boolean isEmpty() { return isEmpty; } - public void markNotEmpty() { isEmpty = false; } + public boolean isEmpty() { return this.isEmpty; } + public void markNotEmpty() { this.isEmpty = false; } @Override public void saveData(IDhLevel level, DataMetaFile file, OutputStream dataStream) throws IOException { DataOutputStream dos = new DataOutputStream(dataStream); // DO NOT CLOSE { - dos.writeInt(getDataDetail()); - dos.writeInt(size); + dos.writeInt(this.getDataDetail()); + dos.writeInt(this.size); dos.writeInt(level.getMinY()); - if (isEmpty) + if (this.isEmpty) { dos.writeInt(0x00000001); return; } dos.writeInt(0xFFFFFFFF); // Data array length - for (int x = 0; x < size; x++) + for (int x = 0; x < this.size; x++) { - for (int z = 0; z < size; z++) + for (int z = 0; z < this.size; z++) { - dos.writeByte(get(x, z).getSingleLength()); + dos.writeByte(this.get(x, z).getSingleLength()); } } // Data array content (only on non-empty columns) dos.writeInt(0xFFFFFFFF); - for (int x = 0; x < size; x++) + for (int x = 0; x < this.size; x++) { - for (int z = 0; z < size; z++) + for (int z = 0; z < this.size; z++) { - SingleFullArrayView column = get(x, z); + SingleFullArrayView column = this.get(x, z); if (!column.doesItExist()) continue; long[] raw = column.getRaw(); @@ -152,7 +152,7 @@ public class FullDataSource extends FullArrayView implements ILodDataSource } // Id mapping dos.writeInt(0xFFFFFFFF); - mapping.serialize(dos); + this.mapping.serialize(dos); dos.writeInt(0xFFFFFFFF); } } @@ -220,7 +220,7 @@ public class FullDataSource extends FullArrayView implements ILodDataSource super(mapping, data, SECTION_SIZE); LodUtil.assertTrue(data.length == SECTION_SIZE * SECTION_SIZE); this.sectionPos = pos; - isEmpty = false; + this.isEmpty = false; } public static FullDataSource createEmpty(DhSectionPos pos) { return new FullDataSource(pos); } @@ -239,14 +239,14 @@ public class FullDataSource extends FullArrayView implements ILodDataSource public void writeFromLower(FullDataSource subData) { - LodUtil.assertTrue(sectionPos.overlaps(subData.sectionPos)); - LodUtil.assertTrue(subData.sectionPos.sectionDetail < sectionPos.sectionDetail); - if (!neededForPosition(sectionPos, subData.sectionPos)) + LodUtil.assertTrue(this.sectionPos.overlaps(subData.sectionPos)); + LodUtil.assertTrue(subData.sectionPos.sectionDetail < this.sectionPos.sectionDetail); + if (!neededForPosition(this.sectionPos, subData.sectionPos)) return; DhSectionPos lowerSectPos = subData.sectionPos; - byte detailDiff = (byte) (sectionPos.sectionDetail - subData.sectionPos.sectionDetail); - byte targetDataDetail = getDataDetail(); - DhLodPos minDataPos = sectionPos.getCorner(targetDataDetail); + byte detailDiff = (byte) (this.sectionPos.sectionDetail - subData.sectionPos.sectionDetail); + byte targetDataDetail = this.getDataDetail(); + DhLodPos minDataPos = this.sectionPos.getCorner(targetDataDetail); if (detailDiff <= SECTION_SIZE_OFFSET) { int count = 1 << detailDiff; diff --git a/core/src/main/java/com/seibel/lod/core/datatype/full/SparseDataSource.java b/core/src/main/java/com/seibel/lod/core/datatype/full/SparseDataSource.java index 2ea7b9e31..8f877930d 100644 --- a/core/src/main/java/com/seibel/lod/core/datatype/full/SparseDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/datatype/full/SparseDataSource.java @@ -33,228 +33,272 @@ public class SparseDataSource implements IIncompleteDataSource final int dataPerChunk; private final DhLodPos chunkPos; public boolean isEmpty = true; + + + + public static SparseDataSource createEmpty(DhSectionPos pos) { return new SparseDataSource(pos); } - public static SparseDataSource createEmpty(DhSectionPos pos) { - return new SparseDataSource(pos); - } - - protected SparseDataSource(DhSectionPos sectionPos) { + protected SparseDataSource(DhSectionPos sectionPos) + { LodUtil.assertTrue(sectionPos.sectionDetail > SPARSE_UNIT_DETAIL); LodUtil.assertTrue(sectionPos.sectionDetail <= MAX_SECTION_DETAIL); this.sectionPos = sectionPos; - chunks = 1 << (byte) (sectionPos.sectionDetail - SPARSE_UNIT_DETAIL); - dataPerChunk = SECTION_SIZE / chunks; - sparseData = new FullArrayView[chunks * chunks]; - chunkPos = sectionPos.getCorner(SPARSE_UNIT_DETAIL); - mapping = new FullDataPointIdMap(); + this.chunks = 1 << (byte) (sectionPos.sectionDetail - SPARSE_UNIT_DETAIL); + this.dataPerChunk = SECTION_SIZE / this.chunks; + this.sparseData = new FullArrayView[this.chunks * this.chunks]; + this.chunkPos = sectionPos.getCorner(SPARSE_UNIT_DETAIL); + this.mapping = new FullDataPointIdMap(); } - protected SparseDataSource(DhSectionPos sectionPos, FullDataPointIdMap mapping, FullArrayView[] data) { + protected SparseDataSource(DhSectionPos sectionPos, FullDataPointIdMap mapping, FullArrayView[] data) + { LodUtil.assertTrue(sectionPos.sectionDetail > SPARSE_UNIT_DETAIL); LodUtil.assertTrue(sectionPos.sectionDetail <= MAX_SECTION_DETAIL); this.sectionPos = sectionPos; - chunks = 1 << (byte) (sectionPos.sectionDetail - SPARSE_UNIT_DETAIL); - dataPerChunk = SECTION_SIZE / chunks; - LodUtil.assertTrue(chunks*chunks == data.length); - sparseData = data; - chunkPos = sectionPos.getCorner(SPARSE_UNIT_DETAIL); - isEmpty = false; + this.chunks = 1 << (byte) (sectionPos.sectionDetail - 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); + this.isEmpty = false; this.mapping = mapping; } + + + + @Override + public DhSectionPos getSectionPos() { return this.sectionPos; } + @Override + public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetail-SECTION_SIZE_OFFSET); } @Override - public DhSectionPos getSectionPos() { - return sectionPos; + public byte getDataVersion() { return LATEST_VERSION; } + + private int calculateOffset(int cx, int cz) + { + int ox = cx - this.chunkPos.x; + int oz = cz - this.chunkPos.z; + LodUtil.assertTrue(ox >= 0 && oz >= 0 && ox < this.chunks && oz < this.chunks); + return ox * this.chunks + oz; } + + @Override - public byte getDataDetail() { - return (byte) (sectionPos.sectionDetail-SECTION_SIZE_OFFSET); + public void update(ChunkSizedData data) + { + if (data.dataDetail != 0) + { + //TODO: Disable the throw and instead just ignore the data. + throw new IllegalArgumentException("SparseDataSource only supports dataDetail 0!"); + } + + int arrayOffset = this.calculateOffset(data.x, data.z); + FullArrayView newArray = new FullArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); + if (this.getDataDetail() == data.dataDetail) + { + data.shadowCopyTo(newArray); + } + else + { + int count = this.dataPerChunk; + int dataPerCount = SPARSE_UNIT_SIZE / this.dataPerChunk; + + for (int ox = 0; ox < count; ox++) + { + for (int oz = 0; oz < count; oz++) + { + SingleFullArrayView column = newArray.get(ox, oz); + column.downsampleFrom(data.subView(dataPerCount, ox * dataPerCount, oz * dataPerCount)); + } + } + } + this.isEmpty = false; + this.sparseData[arrayOffset] = newArray; } - + @Override - public byte getDataVersion() { - return LATEST_VERSION; - } - - private int calculateOffset(int cx, int cz) { - int ox = cx - chunkPos.x; - int oz = cz - chunkPos.z; - LodUtil.assertTrue(ox >= 0 && oz >= 0 && ox < chunks && oz < chunks); - return ox * chunks + oz; - } - - + public boolean isEmpty() { return this.isEmpty; } + + @Override - public void update(ChunkSizedData data) { - if (data.dataDetail != 0) { - //TODO: Disable the throw and instead just ignore the data. - throw new IllegalArgumentException("SparseDataSource only supports dataDetail 0!"); - } - int arrayOffset = calculateOffset(data.x, data.z); - FullArrayView newArray = new FullArrayView(mapping, new long[dataPerChunk * dataPerChunk][], dataPerChunk); - if (getDataDetail() == data.dataDetail) { - data.shadowCopyTo(newArray); - } else { - int count = dataPerChunk; - int dataPerCount = SPARSE_UNIT_SIZE / dataPerChunk; + public void sampleFrom(ILodDataSource source) + { + DhSectionPos pos = source.getSectionPos(); + LodUtil.assertTrue(pos.sectionDetail < this.sectionPos.sectionDetail); + LodUtil.assertTrue(pos.overlaps(this.sectionPos)); + if (source.isEmpty()) + return; + + if (source instanceof SparseDataSource) + { + this.sampleFrom((SparseDataSource) source); + } + else if (source instanceof FullDataSource) + { + this.sampleFrom((FullDataSource) source); + } + else + { + LodUtil.assertNotReach(); + } + } - for (int ox = 0; ox < count; ox++) { - for (int oz = 0; oz < count; oz++) { - SingleFullArrayView column = newArray.get(ox, oz); - column.downsampleFrom(data.subView(dataPerCount, ox * dataPerCount, oz * dataPerCount)); - } - } - } - isEmpty = false; - sparseData[arrayOffset] = newArray; - } - - @Override - public boolean isEmpty() { - return isEmpty; - } - - - @Override - public void sampleFrom(ILodDataSource source) { - DhSectionPos pos = source.getSectionPos(); - LodUtil.assertTrue(pos.sectionDetail < sectionPos.sectionDetail); - LodUtil.assertTrue(pos.overlaps(sectionPos)); - if (source.isEmpty()) return; - if (source instanceof SparseDataSource) { - sampleFrom((SparseDataSource) source); - } else if (source instanceof FullDataSource) { - sampleFrom((FullDataSource) source); - } else { - LodUtil.assertNotReach(); - } - } - - private void sampleFrom(SparseDataSource sparseSource) { + private void sampleFrom(SparseDataSource sparseSource) + { DhSectionPos pos = sparseSource.getSectionPos(); - isEmpty = false; - - DhLodPos basePos = sectionPos.getCorner(SPARSE_UNIT_DETAIL); + 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 < chunks && offsetZ >=0 && offsetZ < chunks); - - for (int ox = 0; ox < sparseSource.chunks; ox++) { - for (int oz = 0; oz < sparseSource.chunks; oz++) { - FullArrayView sourceChunk = sparseSource.sparseData[ox*sparseSource.chunks + oz]; - if (sourceChunk != null) { - FullArrayView buff = new FullArrayView(mapping, new long[dataPerChunk * dataPerChunk][], dataPerChunk); - buff.downsampleFrom(sourceChunk); - sparseData[(ox+offsetX)* chunks + (oz+offsetZ)] = buff; - } - } - } + LodUtil.assertTrue(offsetX >= 0 && offsetX < this.chunks && offsetZ >= 0 && offsetZ < this.chunks); + + for (int ox = 0; ox < sparseSource.chunks; ox++) + { + for (int oz = 0; oz < sparseSource.chunks; oz++) + { + FullArrayView sourceChunk = sparseSource.sparseData[ox * sparseSource.chunks + oz]; + if (sourceChunk != null) + { + FullArrayView buff = new FullArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); + buff.downsampleFrom(sourceChunk); + this.sparseData[(ox + offsetX) * this.chunks + (oz + offsetZ)] = buff; + } + } + } } - private void sampleFrom(FullDataSource fullSource) { + private void sampleFrom(FullDataSource fullSource) + { DhSectionPos pos = fullSource.getSectionPos(); - isEmpty = false; + this.isEmpty = false; - DhLodPos basePos = sectionPos.getCorner(SPARSE_UNIT_DETAIL); + 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.getDataDetail(); LodUtil.assertTrue(coveredChunks*sourceDataPerChunk == FullDataSource.SECTION_SIZE); int offsetX = dataPos.x-basePos.x; int offsetZ = dataPos.z-basePos.z; - LodUtil.assertTrue(offsetX >=0 && offsetX < chunks && offsetZ >=0 && offsetZ < chunks); - - for (int ox = 0; ox < coveredChunks; ox++) { - for (int oz = 0; oz < coveredChunks; oz++) { - FullArrayView sourceChunk = fullSource.subView(sourceDataPerChunk, ox*sourceDataPerChunk, oz*sourceDataPerChunk); - FullArrayView buff = new FullArrayView(mapping, new long[dataPerChunk * dataPerChunk][], dataPerChunk); - buff.downsampleFrom(sourceChunk); - sparseData[(ox+offsetX)* chunks + (oz+offsetZ)] = buff; - } - } + LodUtil.assertTrue(offsetX >=0 && offsetX < this.chunks && offsetZ >=0 && offsetZ < this.chunks); + + for (int ox = 0; ox < coveredChunks; ox++) + { + for (int oz = 0; oz < coveredChunks; oz++) + { + FullArrayView sourceChunk = fullSource.subView(sourceDataPerChunk, ox * sourceDataPerChunk, oz * sourceDataPerChunk); + FullArrayView buff = new FullArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); + buff.downsampleFrom(sourceChunk); + this.sparseData[(ox + offsetX) * this.chunks + (oz + offsetZ)] = buff; + } + } } @Override - public void saveData(IDhLevel level, DataMetaFile file, OutputStream dataStream) throws IOException { - try (DataOutputStream dos = new DataOutputStream(dataStream)) { - dos.writeShort(getDataDetail()); + public void saveData(IDhLevel level, DataMetaFile file, OutputStream dataStream) throws IOException + { + try (DataOutputStream dos = new DataOutputStream(dataStream)) + { + dos.writeShort(this.getDataDetail()); dos.writeShort(SPARSE_UNIT_DETAIL); dos.writeInt(SECTION_SIZE); dos.writeInt(level.getMinY()); - if (isEmpty) { + if (this.isEmpty) + { dos.writeInt(0x00000001); return; } + dos.writeInt(0xFFFFFFFF); // sparse array existence bitset - BitSet set = new BitSet(sparseData.length); - for (int i = 0; i < sparseData.length; i++) set.set(i, sparseData[i] != null); + BitSet set = new BitSet(this.sparseData.length); + for (int i = 0; i < this.sparseData.length; i++) set.set(i, this.sparseData[i] != null); byte[] bytes = set.toByteArray(); dos.writeInt(bytes.length); dos.write(bytes); // Data array content (only on non-empty stuff) dos.writeInt(0xFFFFFFFF); - for (int i = set.nextSetBit(0); i >= 0; i = set.nextSetBit(i + 1)) { - FullArrayView array = sparseData[i]; + for (int i = set.nextSetBit(0); i >= 0; i = set.nextSetBit(i + 1)) + { + FullArrayView array = this.sparseData[i]; LodUtil.assertTrue(array != null); - for (int x = 0; x < array.width(); x++) { - for (int z = 0; z < array.width(); z++) { - dos.writeByte(array.get(x, z).getSingleLength()); - } - } - for (int x = 0; x < array.width(); x++) { - for (int z = 0; z < array.width(); z++) { - SingleFullArrayView column = array.get(x, z); - LodUtil.assertTrue(column.getMapping() == mapping); //MUST be exact equal! - if (!column.doesItExist()) continue; - long[] raw = column.getRaw(); - for (long l : raw) { - dos.writeLong(l); - } - } - } + for (int x = 0; x < array.width(); x++) + { + for (int z = 0; z < array.width(); z++) + { + dos.writeByte(array.get(x, z).getSingleLength()); + } + } + + for (int x = 0; x < array.width(); x++) + { + for (int z = 0; z < array.width(); z++) + { + SingleFullArrayView column = array.get(x, z); + LodUtil.assertTrue(column.getMapping() == this.mapping); //MUST be exact equal! + if (!column.doesItExist()) + continue; + long[] raw = column.getRaw(); + for (long l : raw) + { + dos.writeLong(l); + } + } + } } + // Id mapping dos.writeInt(0xFFFFFFFF); - mapping.serialize(dos); + this.mapping.serialize(dos); dos.writeInt(0xFFFFFFFF); } } - public static SparseDataSource loadData(DataMetaFile dataFile, InputStream dataStream, IDhLevel level) throws IOException { + public static SparseDataSource loadData(DataMetaFile dataFile, InputStream dataStream, IDhLevel level) throws IOException + { LodUtil.assertTrue(dataFile.pos.sectionDetail > SPARSE_UNIT_DETAIL); LodUtil.assertTrue(dataFile.pos.sectionDetail <= MAX_SECTION_DETAIL); + DataInputStream dos = new DataInputStream(dataStream); // DO NOT CLOSE! It would close all related streams { int dataDetail = dos.readShort(); if(dataDetail != dataFile.metaData.dataLevel) throw new IOException(LodUtil.formatLog("Data level mismatch: {} != {}", dataDetail, dataFile.metaData.dataLevel)); + int sparseDetail = dos.readShort(); if (sparseDetail != SPARSE_UNIT_DETAIL) - throw new IOException((LodUtil.formatLog("Unexpected sparse detail level: {} != {}", - sparseDetail, SPARSE_UNIT_DETAIL))); + { + throw new IOException((LodUtil.formatLog("Unexpected sparse detail level: {} != {}", + sparseDetail, SPARSE_UNIT_DETAIL))); + } + int size = dos.readInt(); if (size != SECTION_SIZE) - throw new IOException(LodUtil.formatLog( - "Section size mismatch: {} != {} (Currently only 1 section size is supported)", size, SECTION_SIZE)); + { + throw new IOException(LodUtil.formatLog( + "Section size mismatch: {} != {} (Currently only 1 section size is supported)", size, SECTION_SIZE)); + } + int chunks = 1 << (byte) (dataFile.pos.sectionDetail - sparseDetail); int dataPerChunk = size / chunks; - + int minY = dos.readInt(); if (minY != level.getMinY()) LOGGER.warn("Data minY mismatch: {} != {}. Will ignore data's y level", minY, level.getMinY()); int end = dos.readInt(); // Data array length - if (end == 0x00000001) { + if (end == 0x00000001) + { // Section is empty return createEmpty(dataFile.pos); } // Non-empty section - if (end != 0xFFFFFFFF) throw new IOException("invalid header end guard"); + if (end != 0xFFFFFFFF) + throw new IOException("invalid header end guard"); int length = dos.readInt(); - - if (length < 0 || length > (chunks*chunks/8+64)*2) + + if (length < 0 || length > (chunks * chunks / 8 + 64) * 2) throw new IOException(LodUtil.formatLog("Sparse Flag BitSet size outside reasonable range: {} (expects {} to {})", length, 1, chunks*chunks/8+63)); byte[] bytes = dos.readNBytes(length); @@ -264,70 +308,93 @@ public class SparseDataSource implements IIncompleteDataSource // Data array content (only on non-empty columns) end = dos.readInt(); - if (end != 0xFFFFFFFF) throw new IOException("invalid data length end guard"); - for (int i = set.nextSetBit(0); i >= 0 && i < dataChunks.length; i = set.nextSetBit(i + 1)) { - long[][] dataColumns = new long[dataPerChunk*dataPerChunk][]; - dataChunks[i] = dataColumns; - for (int i2 = 0; i2 < dataColumns.length; i2++) { - dataColumns[i2] = new long[dos.readByte()]; - } - for (int k = 0; k < dataColumns.length; k++) { - if (dataColumns[k].length == 0) continue; - for (int o = 0; o < dataColumns[k].length; o++) { - dataColumns[k][o] = dos.readLong(); - } - } - } + if (end != 0xFFFFFFFF) + throw new IOException("invalid data length end guard"); + + for (int i = set.nextSetBit(0); i >= 0 && i < dataChunks.length; i = set.nextSetBit(i + 1)) + { + long[][] dataColumns = new long[dataPerChunk * dataPerChunk][]; + dataChunks[i] = dataColumns; + for (int i2 = 0; i2 < dataColumns.length; i2++) + { + dataColumns[i2] = new long[dos.readByte()]; + } + for (int k = 0; k < dataColumns.length; k++) + { + if (dataColumns[k].length == 0) + continue; + for (int o = 0; o < dataColumns[k].length; o++) + { + dataColumns[k][o] = dos.readLong(); + } + } + } // Id mapping end = dos.readInt(); - if (end != 0xFFFFFFFF) throw new IOException("invalid data content end guard"); + if (end != 0xFFFFFFFF) + throw new IOException("invalid data content end guard"); + FullDataPointIdMap mapping = FullDataPointIdMap.deserialize(dos); end = dos.readInt(); - if (end != 0xFFFFFFFF) throw new IOException("invalid id mapping end guard"); + if (end != 0xFFFFFFFF) + throw new IOException("invalid id mapping end guard"); FullArrayView[] objectChunks = new FullArrayView[chunks*chunks]; - for (int i=0; i=0 && x=0 && z SparseDataSource.MAX_SECTION_DETAIL); this.sectionPos = sectionPos; - isColumnNotEmpty = new BitSet(SECTION_SIZE*SECTION_SIZE); + this.isColumnNotEmpty = new BitSet(SECTION_SIZE*SECTION_SIZE); } @Override - public DhSectionPos getSectionPos() { - return sectionPos; - } + public DhSectionPos getSectionPos() { return this.sectionPos; } @Override - public byte getDataDetail() { - return (byte) (sectionPos.sectionDetail-SECTION_SIZE_OFFSET); - } + public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetail-SECTION_SIZE_OFFSET); } @Override - public byte getDataVersion() { - return LATEST_VERSION; - } + public byte getDataVersion() { return LATEST_VERSION; } @Override - public void update(ChunkSizedData data) { - LodUtil.assertTrue(sectionPos.getSectionBBoxPos().overlaps(data.getBBoxLodPos())); + public void update(ChunkSizedData data) + { + LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlaps(data.getBBoxLodPos())); - if (data.dataDetail == 0 && getDataDetail() >= 4) { + if (data.dataDetail == 0 && this.getDataDetail() >= 4) + { //FIXME: TEMPORARY - int chunkPerFull = 1 << (getDataDetail() - 4); - if (data.x % chunkPerFull != 0 || data.z % chunkPerFull != 0) return; - DhLodPos baseOffset = sectionPos.getCorner(getDataDetail()); - DhLodPos dataOffset = data.getBBoxLodPos().convertUpwardsTo(getDataDetail()); + int chunkPerFull = 1 << (this.getDataDetail() - 4); + if (data.x % chunkPerFull != 0 || data.z % chunkPerFull != 0) + return; + DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail()); + DhLodPos dataOffset = data.getBBoxLodPos().convertUpwardsTo(this.getDataDetail()); int offsetX = dataOffset.x - baseOffset.x; int offsetZ = dataOffset.z - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); - isEmpty = false; - data.get(0,0).deepCopyTo(get(offsetX, offsetZ)); - } else { + this.isEmpty = false; + data.get(0,0).deepCopyTo(this.get(offsetX, offsetZ)); + } + else + { LodUtil.assertNotReach(); //TODO; } @@ -70,89 +74,99 @@ public class SpottyDataSource extends FullArrayView implements IIncompleteDataSo } @Override - public boolean isEmpty() { - return isEmpty; - } + public boolean isEmpty() { return this.isEmpty; } - public void markNotEmpty() { - isEmpty = false; - } + public void markNotEmpty() { this.isEmpty = false; } @Override - public void saveData(IDhLevel level, DataMetaFile file, OutputStream dataStream) throws IOException { + public void saveData(IDhLevel level, DataMetaFile file, OutputStream dataStream) throws IOException + { DataOutputStream dos = new DataOutputStream(dataStream); // DO NOT CLOSE { - dos.writeInt(getDataDetail()); - dos.writeInt(size); + dos.writeInt(this.getDataDetail()); + dos.writeInt(this.size); dos.writeInt(level.getMinY()); - if (isEmpty) { + if (this.isEmpty) + { dos.writeInt(0x00000001); return; } // Is column not empty dos.writeInt(0xFFFFFFFF); - byte[] bytes = isColumnNotEmpty.toByteArray(); + byte[] bytes = this.isColumnNotEmpty.toByteArray(); dos.writeInt(bytes.length); dos.write(bytes); // Data array content dos.writeInt(0xFFFFFFFF); - for (int i = isColumnNotEmpty.nextSetBit(0); i >= 0; i = isColumnNotEmpty.nextSetBit(i + 1)) + for (int i = this.isColumnNotEmpty.nextSetBit(0); i >= 0; i = this.isColumnNotEmpty.nextSetBit(i + 1)) { - dos.writeByte(dataArrays[i].length); - if (dataArrays[i].length == 0) continue; - for (long l : dataArrays[i]) { + dos.writeByte(this.dataArrays[i].length); + if (this.dataArrays[i].length == 0) + continue; + for (long l : this.dataArrays[i]) { dos.writeLong(l); } } // Id mapping dos.writeInt(0xFFFFFFFF); - mapping.serialize(dos); + this.mapping.serialize(dos); dos.writeInt(0xFFFFFFFF); } } - public static SpottyDataSource loadData(DataMetaFile dataFile, InputStream dataStream, IDhLevel level) throws IOException { + public static SpottyDataSource loadData(DataMetaFile dataFile, InputStream dataStream, IDhLevel level) throws IOException + { DataInputStream dos = new DataInputStream(dataStream); // DO NOT CLOSE { int dataDetail = dos.readInt(); if(dataDetail != dataFile.metaData.dataLevel) throw new IOException(LodUtil.formatLog("Data level mismatch: {} != {}", dataDetail, dataFile.metaData.dataLevel)); + int size = dos.readInt(); if (size != SECTION_SIZE) throw new IOException(LodUtil.formatLog( "Section size mismatch: {} != {} (Currently only 1 section size is supported)", size, SECTION_SIZE)); + int minY = dos.readInt(); if (minY != level.getMinY()) LOGGER.warn("Data minY mismatch: {} != {}. Will ignore data's y level", minY, level.getMinY()); + int end = dos.readInt(); // Data array length - if (end == 0x00000001) { + if (end == 0x00000001) + { // Section is empty return new SpottyDataSource(dataFile.pos); } // Is column not empty - if (end != 0xFFFFFFFF) throw new IOException("invalid header end guard"); + if (end != 0xFFFFFFFF) + throw new IOException("invalid header end guard"); int length = dos.readInt(); if (length < 0 || length > (SECTION_SIZE*SECTION_SIZE/8+64)*2) - throw new IOException(LodUtil.formatLog("Spotty Flag BitSet size outside reasonable range: {} (expects {} to {})", - length, 1, SECTION_SIZE*SECTION_SIZE/8+63)); + { + throw new IOException(LodUtil.formatLog("Spotty Flag BitSet size outside reasonable range: {} (expects {} to {})", + length, 1, SECTION_SIZE * SECTION_SIZE / 8 + 63)); + } byte[] bytes = dos.readNBytes(length); BitSet isColumnNotEmpty = BitSet.valueOf(bytes); // Data array content long[][] data = new long[SECTION_SIZE*SECTION_SIZE][]; end = dos.readInt(); - if (end != 0xFFFFFFFF) throw new IOException("invalid spotty flag end guard"); + if (end != 0xFFFFFFFF) + throw new IOException("invalid spotty flag end guard"); + for (int i = isColumnNotEmpty.nextSetBit(0); i >= 0; i = isColumnNotEmpty.nextSetBit(i + 1)) { long[] array = new long[dos.readByte()]; - for (int j = 0; j < array.length; j++) { + for (int j = 0; j < array.length; j++) + { array[j] = dos.readLong(); } data[i] = array; @@ -160,128 +174,158 @@ public class SpottyDataSource extends FullArrayView implements IIncompleteDataSo // Id mapping end = dos.readInt(); - if (end != 0xFFFFFFFF) throw new IOException("invalid data content end guard"); + if (end != 0xFFFFFFFF) + throw new IOException("invalid data content end guard"); + FullDataPointIdMap mapping = FullDataPointIdMap.deserialize(new UnclosableInputStream(dos)); end = dos.readInt(); - if (end != 0xFFFFFFFF) throw new IOException("invalid id mapping end guard"); + if (end != 0xFFFFFFFF) + throw new IOException("invalid id mapping end guard"); + return new SpottyDataSource(dataFile.pos, mapping, isColumnNotEmpty, data); } } - private SpottyDataSource(DhSectionPos pos, FullDataPointIdMap mapping, BitSet isColumnNotEmpty, long[][] data) { + private SpottyDataSource(DhSectionPos pos, FullDataPointIdMap mapping, BitSet isColumnNotEmpty, long[][] data) + { super(mapping, data, SECTION_SIZE); LodUtil.assertTrue(data.length == SECTION_SIZE*SECTION_SIZE); this.sectionPos = pos; this.isColumnNotEmpty = isColumnNotEmpty; - isEmpty = false; + this.isEmpty = false; } - public static SpottyDataSource createEmpty(DhSectionPos pos) { - return new SpottyDataSource(pos); - } + public static SpottyDataSource createEmpty(DhSectionPos pos) { return new SpottyDataSource(pos); } - public static boolean neededForPosition(DhSectionPos posToWrite, DhSectionPos posToTest) { - if (!posToWrite.overlaps(posToTest)) return false; - if (posToTest.sectionDetail > posToWrite.sectionDetail) return false; - if (posToWrite.sectionDetail - posToTest.sectionDetail <= SECTION_SIZE_OFFSET) return true; + public static boolean neededForPosition(DhSectionPos posToWrite, DhSectionPos posToTest) + { + if (!posToWrite.overlaps(posToTest)) + return false; + if (posToTest.sectionDetail > posToWrite.sectionDetail) + return false; + if (posToWrite.sectionDetail - posToTest.sectionDetail <= SECTION_SIZE_OFFSET) + return true; byte sectPerData = (byte) (1 << (posToWrite.sectionDetail - posToTest.sectionDetail - SECTION_SIZE_OFFSET)); return posToTest.sectionX % sectPerData == 0 && posToTest.sectionZ % sectPerData == 0; } @Override - public void sampleFrom(ILodDataSource source) { + public void sampleFrom(ILodDataSource source) + { DhSectionPos pos = source.getSectionPos(); - LodUtil.assertTrue(pos.sectionDetail < sectionPos.sectionDetail); - LodUtil.assertTrue(pos.overlaps(sectionPos)); - if (source.isEmpty()) return; - if (source instanceof SparseDataSource) { - sampleFrom((SparseDataSource) source); - } else if (source instanceof FullDataSource) { - sampleFrom((FullDataSource) source); - } else { + LodUtil.assertTrue(pos.sectionDetail < this.sectionPos.sectionDetail); + LodUtil.assertTrue(pos.overlaps(this.sectionPos)); + if (source.isEmpty()) + return; + + if (source instanceof SparseDataSource) + { + this.sampleFrom((SparseDataSource) source); + } + else if (source instanceof FullDataSource) + { + this.sampleFrom((FullDataSource) source); + } + else + { LodUtil.assertNotReach(); } } - private void sampleFrom(SparseDataSource sparseSource) { + private void sampleFrom(SparseDataSource sparseSource) + { DhSectionPos pos = sparseSource.getSectionPos(); - isEmpty = false; + this.isEmpty = false; - if (getDataDetail() > sectionPos.sectionDetail) { - DhLodPos basePos = sectionPos.getCorner(getDataDetail()); - DhLodPos dataPos = pos.getCorner(getDataDetail()); + if (this.getDataDetail() > this.sectionPos.sectionDetail) + { + DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail()); + DhLodPos dataPos = pos.getCorner(this.getDataDetail()); int offsetX = dataPos.x - basePos.x; int offsetZ = dataPos.z - basePos.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); - int chunksPerData = 1 << (getDataDetail() - SparseDataSource.SPARSE_UNIT_DETAIL); - int dataSpan = sectionPos.getWidth(getDataDetail()).numberOfLodSectionsWide; + int chunksPerData = 1 << (this.getDataDetail() - SparseDataSource.SPARSE_UNIT_DETAIL); + int dataSpan = this.sectionPos.getWidth(this.getDataDetail()).numberOfLodSectionsWide; - for (int ox = 0; ox < dataSpan; ox++) { - for (int oz = 0; oz < dataSpan; oz++) { + for (int ox = 0; ox < dataSpan; ox++) + { + for (int oz = 0; oz < dataSpan; oz++) + { SingleFullArrayView column = sparseSource.tryGet( ox * chunksPerData * sparseSource.dataPerChunk, oz * chunksPerData * sparseSource.dataPerChunk); - if (column != null) { - column.deepCopyTo(get(offsetX + ox, offsetZ + oz)); - isColumnNotEmpty.set((offsetX + ox) * SECTION_SIZE + offsetZ + oz, true); + if (column != null) + { + column.deepCopyTo(this.get(offsetX + ox, offsetZ + oz)); + this.isColumnNotEmpty.set((offsetX + ox) * SECTION_SIZE + offsetZ + oz, true); } } } - } else { + } + else + { DhLodPos dataPos = pos.getSectionBBoxPos(); - int lowerSectionsPerData = sectionPos.getWidth(dataPos.detailLevel).numberOfLodSectionsWide; + int lowerSectionsPerData = this.sectionPos.getWidth(dataPos.detailLevel).numberOfLodSectionsWide; if (dataPos.x % lowerSectionsPerData != 0 || dataPos.z % lowerSectionsPerData != 0) return; - DhLodPos basePos = sectionPos.getCorner(getDataDetail()); - dataPos = dataPos.convertUpwardsTo(getDataDetail()); + DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail()); + dataPos = dataPos.convertUpwardsTo(this.getDataDetail()); int offsetX = dataPos.x - basePos.x; int offsetZ = dataPos.z - basePos.z; SingleFullArrayView column = sparseSource.tryGet(0, 0); if (column != null) { - column.deepCopyTo(get(offsetX, offsetZ)); - isColumnNotEmpty.set(offsetX * SECTION_SIZE + offsetZ, true); + column.deepCopyTo(this.get(offsetX, offsetZ)); + this.isColumnNotEmpty.set(offsetX * SECTION_SIZE + offsetZ, true); } } } - private void sampleFrom(FullDataSource fullSource) { + private void sampleFrom(FullDataSource fullSource) + { DhSectionPos pos = fullSource.getSectionPos(); - isEmpty = false; - downsampleFrom(fullSource); - - if (getDataDetail() > sectionPos.sectionDetail) { - DhLodPos basePos = sectionPos.getCorner(getDataDetail()); - DhLodPos dataPos = pos.getCorner(getDataDetail()); - int offsetX = dataPos.x - basePos.x; - int offsetZ = dataPos.z - basePos.z; - int dataSpan = sectionPos.getWidth(getDataDetail()).numberOfLodSectionsWide; - for (int ox = 0; ox < dataSpan; ox++) { - for (int oz = 0; oz < dataSpan; oz++) { - isColumnNotEmpty.set((offsetX + ox) * SECTION_SIZE + offsetZ + oz, true); - } - } - } else { + this.isEmpty = false; + this.downsampleFrom(fullSource); + + if (this.getDataDetail() > this.sectionPos.sectionDetail) + { + DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail()); + DhLodPos dataPos = pos.getCorner(this.getDataDetail()); + int offsetX = dataPos.x - basePos.x; + int offsetZ = dataPos.z - basePos.z; + int dataSpan = this.sectionPos.getWidth(this.getDataDetail()).numberOfLodSectionsWide; + for (int ox = 0; ox < dataSpan; ox++) + { + for (int oz = 0; oz < dataSpan; oz++) + { + this.isColumnNotEmpty.set((offsetX + ox) * SECTION_SIZE + offsetZ + oz, true); + } + } + } + else + { DhLodPos dataPos = pos.getSectionBBoxPos(); - int lowerSectionsPerData = sectionPos.getWidth(dataPos.detailLevel).numberOfLodSectionsWide; + int lowerSectionsPerData = this.sectionPos.getWidth(dataPos.detailLevel).numberOfLodSectionsWide; if (dataPos.x % lowerSectionsPerData != 0 || dataPos.z % lowerSectionsPerData != 0) return; - DhLodPos basePos = sectionPos.getCorner(getDataDetail()); - dataPos = dataPos.convertUpwardsTo(getDataDetail()); + DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail()); + dataPos = dataPos.convertUpwardsTo(this.getDataDetail()); int offsetX = dataPos.x - basePos.x; int offsetZ = dataPos.z - basePos.z; - isColumnNotEmpty.set(offsetX * SECTION_SIZE + offsetZ, true); + this.isColumnNotEmpty.set(offsetX * SECTION_SIZE + offsetZ, true); } } @Override - public ILodDataSource trySelfPromote() { - if (isEmpty) return this; - if (isColumnNotEmpty.cardinality() != SECTION_SIZE * SECTION_SIZE) return this; - return new FullDataSource(sectionPos, mapping, dataArrays); + public ILodDataSource trySelfPromote() + { + if (this.isEmpty) + return this; + if (this.isColumnNotEmpty.cardinality() != SECTION_SIZE * SECTION_SIZE) + return this; + return new FullDataSource(this.sectionPos, this.mapping, this.dataArrays); } @Override - public SingleFullArrayView tryGet(int x, int z) { - return isColumnNotEmpty.get(x * SECTION_SIZE + z) ? get(x, z) : null; - } + public SingleFullArrayView tryGet(int x, int z) { return this.isColumnNotEmpty.get(x * SECTION_SIZE + z) ? this.get(x, z) : null; } + } diff --git a/core/src/main/java/com/seibel/lod/core/datatype/full/accessor/FullArrayView.java b/core/src/main/java/com/seibel/lod/core/datatype/full/accessor/FullArrayView.java index aff3ee883..43367c8d2 100644 --- a/core/src/main/java/com/seibel/lod/core/datatype/full/accessor/FullArrayView.java +++ b/core/src/main/java/com/seibel/lod/core/datatype/full/accessor/FullArrayView.java @@ -21,7 +21,7 @@ public class FullArrayView implements IFullDataView this.size = size; this.dataSize = size; this.mapping = mapping; - offset = 0; + this.offset = 0; } public FullArrayView(FullArrayView source, int size, int offsetX, int offsetZ) @@ -29,66 +29,51 @@ public class FullArrayView implements IFullDataView if (source.size < size || source.size < size + offsetX || source.size < size + offsetZ) throw new IllegalArgumentException( "tried constructing dataArrayView subview with invalid input!"); - dataArrays = source.dataArrays; + this.dataArrays = source.dataArrays; this.size = size; this.dataSize = source.dataSize; - mapping = source.mapping; - offset = source.offset + offsetX * dataSize + offsetZ; + this.mapping = source.mapping; + this.offset = source.offset + offsetX * this.dataSize + offsetZ; } @Override - public FullDataPointIdMap getMapping() - { - return mapping; - } + public FullDataPointIdMap getMapping() { return this.mapping; } @Override - public SingleFullArrayView get(int index) - { - return get(index / size, index % size); - } + public SingleFullArrayView get(int index) { return this.get(index / this.size, index % this.size); } @Override - public SingleFullArrayView get(int x, int z) - { - return new SingleFullArrayView(mapping, dataArrays, x * size + z + offset); - } + public SingleFullArrayView get(int x, int z) { return new SingleFullArrayView(this.mapping, this.dataArrays, x * this.size + z + this.offset); } @Override - public int width() - { - return size; - } + public int width() { return this.size; } @Override - public FullArrayView subView(int size, int ox, int oz) - { - return new FullArrayView(this, size, ox, oz); - } + public FullArrayView subView(int size, int ox, int oz) { return new FullArrayView(this, size, ox, oz); } /** WARNING: This will potentially share the underlying array object! */ public void shadowCopyTo(FullArrayView target) { - if (target.size != size) + if (target.size != this.size) { throw new IllegalArgumentException("Target view must have same size as this view"); } - if (target.mapping.equals(mapping)) + if (target.mapping.equals(this.mapping)) { - for (int x = 0; x < size; x++) + for (int x = 0; x < this.size; x++) { - System.arraycopy(dataArrays, offset + x * dataSize, - target.dataArrays, target.offset + x * target.dataSize, size); + System.arraycopy(this.dataArrays, this.offset + x * this.dataSize, + target.dataArrays, target.offset + x * target.dataSize, this.size); } } else { - int[] remappedIds = target.mapping.mergeAndReturnRemappedEntityIds(mapping); - for (int x = 0; x < size; x++) + int[] remappedIds = target.mapping.mergeAndReturnRemappedEntityIds(this.mapping); + for (int x = 0; x < this.size; x++) { - for (int o = 0; o < size; o++) + for (int o = 0; o < this.size; o++) { - long[] sourceData = dataArrays[offset + x * dataSize + o]; + long[] sourceData = this.dataArrays[this.offset + x * this.dataSize + o]; long[] newData = new long[sourceData.length]; for (int i = 0; i < newData.length; i++) { @@ -102,15 +87,16 @@ public class FullArrayView implements IFullDataView public void downsampleFrom(FullArrayView source) { - LodUtil.assertTrue(source.size > size && source.size % size == 0); - int dataPerUnit = source.size / size; - for (int ox = 0; ox < size; ox++) + LodUtil.assertTrue(source.size > this.size && source.size % this.size == 0); + int dataPerUnit = source.size / this.size; + for (int ox = 0; ox < this.size; ox++) { - for (int oz = 0; oz < size; oz++) + for (int oz = 0; oz < this.size; oz++) { - SingleFullArrayView column = get(ox, oz); + SingleFullArrayView column = this.get(ox, oz); column.downsampleFrom(source.subView(dataPerUnit, ox * dataPerUnit, oz * dataPerUnit)); } } } + } diff --git a/core/src/main/java/com/seibel/lod/core/file/datafile/DataFileHandler.java b/core/src/main/java/com/seibel/lod/core/file/datafile/DataFileHandler.java index f08a20f53..c920c997b 100644 --- a/core/src/main/java/com/seibel/lod/core/file/datafile/DataFileHandler.java +++ b/core/src/main/java/com/seibel/lod/core/file/datafile/DataFileHandler.java @@ -213,7 +213,10 @@ public class DataFileHandler implements IDataSourceProvider { } - /* + /** + * Returns the 64 x 64 data source for the given section position.
+ * If the section hasn't been generated this will also send a generation call, which may take a while.

+ * * This call is concurrent. I.e. it supports multiple threads calling this method at the same time. */ @Override diff --git a/core/src/main/java/com/seibel/lod/core/pos/DhLodPos.java b/core/src/main/java/com/seibel/lod/core/pos/DhLodPos.java index bcbf7ab63..edff272da 100644 --- a/core/src/main/java/com/seibel/lod/core/pos/DhLodPos.java +++ b/core/src/main/java/com/seibel/lod/core/pos/DhLodPos.java @@ -112,8 +112,8 @@ public class DhLodPos implements Comparable throw new IllegalArgumentException("add called with width.detailLevel < pos detail"); return new DhLodPos(this.detailLevel, - x + width.createFromDetailLevel(this.detailLevel).numberOfLodSectionsWide, - z + width.createFromDetailLevel(this.detailLevel).numberOfLodSectionsWide); + this.x + width.createFromDetailLevel(this.detailLevel).numberOfLodSectionsWide, + this.z + width.createFromDetailLevel(this.detailLevel).numberOfLodSectionsWide); } /** Equivalent to adding a DhLodUnit with the same detail level as this DhLodPos */ @@ -140,7 +140,7 @@ public class DhLodPos implements Comparable } @Override - public int hashCode() { return Objects.hash(detailLevel, x, z); } + public int hashCode() { return Objects.hash(this.detailLevel, this.x, this.z); } @Override public int compareTo(@NotNull DhLodPos obj)