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
+ * 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