Rename and refactor several FullData source/view files
This commit is contained in:
+30
-30
@@ -1,7 +1,7 @@
|
||||
package com.seibel.lod.core.dataObjects.fullData;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.file.fullDatafile.IFullDataSourceProvider;
|
||||
import com.seibel.lod.core.pos.DhLodPos;
|
||||
@@ -17,23 +17,23 @@ public class FullDataDownSampler {
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static CompletableFuture<IFullDataSource> createDownSamplingFuture(DhSectionPos newTarget, IFullDataSourceProvider provider) {
|
||||
// TODO: Make this future somehow run with lowest priority (to ensure ram usage stays low)
|
||||
return createDownSamplingFuture(FullDataSource.createEmpty(newTarget), provider);
|
||||
return createDownSamplingFuture(CompleteFullDataSource.createEmpty(newTarget), provider);
|
||||
}
|
||||
|
||||
public static CompletableFuture<IFullDataSource> createDownSamplingFuture(FullDataSource target, IFullDataSourceProvider provider) {
|
||||
int sectionSizeNeeded = 1 << target.getDataDetail();
|
||||
public static CompletableFuture<IFullDataSource> createDownSamplingFuture(CompleteFullDataSource target, IFullDataSourceProvider provider) {
|
||||
int sectionSizeNeeded = 1 << target.getDataDetailLevel();
|
||||
|
||||
ArrayList<CompletableFuture<IFullDataSource>> futures;
|
||||
DhLodPos basePos = target.getSectionPos().getSectionBBoxPos().getCornerLodPos(FullDataSource.SECTION_SIZE_OFFSET);
|
||||
if (sectionSizeNeeded <= FullDataSource.SECTION_SIZE_OFFSET) {
|
||||
DhLodPos basePos = target.getSectionPos().getSectionBBoxPos().getCornerLodPos(CompleteFullDataSource.SECTION_SIZE_OFFSET);
|
||||
if (sectionSizeNeeded <= CompleteFullDataSource.SECTION_SIZE_OFFSET) {
|
||||
futures = new ArrayList<>(sectionSizeNeeded * sectionSizeNeeded);
|
||||
for (int ox = 0; ox < sectionSizeNeeded; ox++) {
|
||||
for (int oz = 0; oz < sectionSizeNeeded; oz++) {
|
||||
CompletableFuture<IFullDataSource> future = provider.read(new DhSectionPos(
|
||||
FullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox, basePos.z + oz));
|
||||
CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox, basePos.z + oz));
|
||||
future = future.whenComplete((source, ex) -> {
|
||||
if (ex == null && source != null && source instanceof FullDataSource) {
|
||||
downSample(target, (FullDataSource) source);
|
||||
if (ex == null && source != null && source instanceof CompleteFullDataSource) {
|
||||
downSample(target, (CompleteFullDataSource) source);
|
||||
} else if (ex != null) {
|
||||
LOGGER.error("Error while down sampling", ex);
|
||||
}
|
||||
@@ -42,15 +42,15 @@ public class FullDataDownSampler {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
futures = new ArrayList<>(FullDataSource.SECTION_SIZE * FullDataSource.SECTION_SIZE);
|
||||
int multiplier = sectionSizeNeeded / FullDataSource.SECTION_SIZE;
|
||||
for (int ox = 0; ox < FullDataSource.SECTION_SIZE; ox++) {
|
||||
for (int oz = 0; oz < FullDataSource.SECTION_SIZE; oz++) {
|
||||
futures = new ArrayList<>(CompleteFullDataSource.SECTION_SIZE * CompleteFullDataSource.SECTION_SIZE);
|
||||
int multiplier = sectionSizeNeeded / CompleteFullDataSource.SECTION_SIZE;
|
||||
for (int ox = 0; ox < CompleteFullDataSource.SECTION_SIZE; ox++) {
|
||||
for (int oz = 0; oz < CompleteFullDataSource.SECTION_SIZE; oz++) {
|
||||
CompletableFuture<IFullDataSource> future = provider.read(new DhSectionPos(
|
||||
FullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox * multiplier, basePos.z + oz * multiplier));
|
||||
CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox * multiplier, basePos.z + oz * multiplier));
|
||||
future = future.whenComplete((source, ex) -> {
|
||||
if (ex == null && source != null && source instanceof FullDataSource) {
|
||||
downSample(target, (FullDataSource) source);
|
||||
if (ex == null && source != null && source instanceof CompleteFullDataSource) {
|
||||
downSample(target, (CompleteFullDataSource) source);
|
||||
} else if (ex != null) {
|
||||
LOGGER.error("Error while down sampling", ex);
|
||||
}
|
||||
@@ -62,41 +62,41 @@ public class FullDataDownSampler {
|
||||
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenApply(v -> target);
|
||||
}
|
||||
|
||||
public static void downSample(FullDataSource target, FullDataSource source) {
|
||||
public static void downSample(CompleteFullDataSource target, CompleteFullDataSource source) {
|
||||
LodUtil.assertTrue(target.getSectionPos().overlaps(source.getSectionPos()));
|
||||
LodUtil.assertTrue(target.getDataDetail() > source.getDataDetail());
|
||||
LodUtil.assertTrue(target.getDataDetailLevel() > source.getDataDetailLevel());
|
||||
|
||||
byte detailDiff = (byte) (target.getDataDetail() - source.getDataDetail());
|
||||
byte detailDiff = (byte) (target.getDataDetailLevel() - source.getDataDetailLevel());
|
||||
DhSectionPos trgPos = target.getSectionPos();
|
||||
DhSectionPos srcPos = source.getSectionPos();
|
||||
|
||||
if (detailDiff >= FullDataSource.SECTION_SIZE_OFFSET) {
|
||||
if (detailDiff >= CompleteFullDataSource.SECTION_SIZE_OFFSET) {
|
||||
// The source occupies only 1 datapoint in the target
|
||||
// FIXME: TEMP method for down-sampling: take only the corner column
|
||||
int sourceSectionPerTargetData = 1 << (detailDiff - FullDataSource.SECTION_SIZE_OFFSET);
|
||||
int sourceSectionPerTargetData = 1 << (detailDiff - CompleteFullDataSource.SECTION_SIZE_OFFSET);
|
||||
if (srcPos.sectionX % sourceSectionPerTargetData != 0 || srcPos.sectionZ % sourceSectionPerTargetData != 0) {
|
||||
return;
|
||||
}
|
||||
DhLodPos trgOffset = trgPos.getCorner(target.getDataDetail());
|
||||
DhLodPos srcOffset = srcPos.getSectionBBoxPos().convertToDetailLevel(target.getDataDetail());
|
||||
DhLodPos trgOffset = trgPos.getCorner(target.getDataDetailLevel());
|
||||
DhLodPos srcOffset = srcPos.getSectionBBoxPos().convertToDetailLevel(target.getDataDetailLevel());
|
||||
int offsetX = trgOffset.x - srcOffset.x;
|
||||
int offsetZ = trgOffset.z - srcOffset.z;
|
||||
LodUtil.assertTrue(offsetX >= 0 && offsetX < FullDataSource.SECTION_SIZE
|
||||
&& offsetZ >= 0 && offsetZ < FullDataSource.SECTION_SIZE);
|
||||
LodUtil.assertTrue(offsetX >= 0 && offsetX < CompleteFullDataSource.SECTION_SIZE
|
||||
&& offsetZ >= 0 && offsetZ < CompleteFullDataSource.SECTION_SIZE);
|
||||
target.markNotEmpty();
|
||||
source.get(0,0).deepCopyTo(target.get(offsetX, offsetZ));
|
||||
|
||||
} else if (detailDiff > 0) {
|
||||
// The source occupies multiple data-points in the target
|
||||
int srcDataPerTrgData = 1 << detailDiff;
|
||||
int overlappedTrgDataSize = FullDataSource.SECTION_SIZE / srcDataPerTrgData;
|
||||
int overlappedTrgDataSize = CompleteFullDataSource.SECTION_SIZE / srcDataPerTrgData;
|
||||
|
||||
DhLodPos trgOffset = trgPos.getCorner(target.getDataDetail());
|
||||
DhLodPos srcOffset = srcPos.getSectionBBoxPos().getCornerLodPos(target.getDataDetail());
|
||||
DhLodPos trgOffset = trgPos.getCorner(target.getDataDetailLevel());
|
||||
DhLodPos srcOffset = srcPos.getSectionBBoxPos().getCornerLodPos(target.getDataDetailLevel());
|
||||
int offsetX = trgOffset.x - srcOffset.x;
|
||||
int offsetZ = trgOffset.z - srcOffset.z;
|
||||
LodUtil.assertTrue(offsetX >= 0 && offsetX < FullDataSource.SECTION_SIZE
|
||||
&& offsetZ >= 0 && offsetZ < FullDataSource.SECTION_SIZE);
|
||||
LodUtil.assertTrue(offsetX >= 0 && offsetX < CompleteFullDataSource.SECTION_SIZE
|
||||
&& offsetZ >= 0 && offsetZ < CompleteFullDataSource.SECTION_SIZE);
|
||||
target.markNotEmpty();
|
||||
|
||||
for (int ox = 0; ox < overlappedTrgDataSize; ox++) {
|
||||
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.seibel.lod.core.dataObjects.fullData.accessor;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.lod.core.pos.DhChunkPos;
|
||||
import com.seibel.lod.core.pos.DhLodPos;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
|
||||
/**
|
||||
* Contains the Full Data for a single chunk.
|
||||
*/
|
||||
public class ChunkSizedFullDataView extends FullDataArrayView
|
||||
{
|
||||
public final DhChunkPos pos;
|
||||
// TODO replace this var with LodUtil.BLOCK_DETAIL_LEVEL
|
||||
public final byte detailLevel = LodUtil.BLOCK_DETAIL_LEVEL;
|
||||
|
||||
|
||||
|
||||
public ChunkSizedFullDataView(DhChunkPos pos)
|
||||
{
|
||||
super(new FullDataPointIdMap(),
|
||||
new long[LodUtil.CHUNK_WIDTH * LodUtil.CHUNK_WIDTH][0],
|
||||
LodUtil.CHUNK_WIDTH);
|
||||
|
||||
this.pos = pos;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setSingleColumn(long[] data, int x, int z)
|
||||
{
|
||||
dataArrays[x * LodUtil.CHUNK_WIDTH + z] = data;
|
||||
}
|
||||
|
||||
public long nonEmptyCount()
|
||||
{
|
||||
long count = 0;
|
||||
for (long[] data : dataArrays)
|
||||
{
|
||||
if (data.length != 0)
|
||||
{
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public long emptyCount() { return LodUtil.CHUNK_WIDTH * LodUtil.CHUNK_WIDTH - nonEmptyCount(); }
|
||||
|
||||
public DhLodPos getLodPos() { return new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, pos.x, pos.z); }
|
||||
|
||||
}
|
||||
-112
@@ -1,112 +0,0 @@
|
||||
package com.seibel.lod.core.dataObjects.fullData.accessor;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.lod.core.util.FullDataPointUtil;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
|
||||
public class FullArrayView implements IFullDataView
|
||||
{
|
||||
protected final long[][] dataArrays;
|
||||
protected final int offset;
|
||||
protected final int size;
|
||||
protected final int dataSize;
|
||||
protected final FullDataPointIdMap mapping;
|
||||
|
||||
|
||||
|
||||
public FullArrayView(FullDataPointIdMap mapping, long[][] dataArrays, int size)
|
||||
{
|
||||
if (dataArrays.length != size * size)
|
||||
{
|
||||
throw new IllegalArgumentException("tried constructing dataArrayView with invalid input!");
|
||||
}
|
||||
|
||||
this.dataArrays = dataArrays;
|
||||
this.size = size;
|
||||
this.dataSize = size;
|
||||
this.mapping = mapping;
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
public FullArrayView(FullArrayView source, int size, int offsetX, int offsetZ)
|
||||
{
|
||||
if (source.size < size || source.size < size + offsetX || source.size < size + offsetZ)
|
||||
{
|
||||
throw new IllegalArgumentException("tried constructing dataArrayView subview with invalid input!");
|
||||
}
|
||||
|
||||
this.dataArrays = source.dataArrays;
|
||||
this.size = size;
|
||||
this.dataSize = source.dataSize;
|
||||
this.mapping = source.mapping;
|
||||
this.offset = source.offset + offsetX * this.dataSize + offsetZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public FullDataPointIdMap getMapping() { return this.mapping; }
|
||||
|
||||
@Override
|
||||
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(this.mapping, this.dataArrays, x * this.size + z + this.offset); }
|
||||
|
||||
@Override
|
||||
public int width() { return this.size; }
|
||||
|
||||
@Override
|
||||
public FullArrayView subView(int size, int xOffset, int zOffset) { return new FullArrayView(this, size, xOffset, zOffset); }
|
||||
|
||||
/** WARNING: This will potentially share the underlying array object! */
|
||||
public void shadowCopyTo(FullArrayView target)
|
||||
{
|
||||
if (target.size != this.size)
|
||||
{
|
||||
throw new IllegalArgumentException("Target view must have same size as this view");
|
||||
}
|
||||
|
||||
if (target.mapping.equals(this.mapping))
|
||||
{
|
||||
for (int x = 0; x < this.size; x++)
|
||||
{
|
||||
System.arraycopy(this.dataArrays, this.offset + x * this.dataSize,
|
||||
target.dataArrays, target.offset + x * target.dataSize, this.size);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int[] remappedIds = target.mapping.mergeAndReturnRemappedEntityIds(this.mapping);
|
||||
for (int x = 0; x < this.size; x++)
|
||||
{
|
||||
for (int o = 0; o < this.size; 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++)
|
||||
{
|
||||
newData[i] = FullDataPointUtil.remap(remappedIds, sourceData[i]);
|
||||
}
|
||||
|
||||
target.dataArrays[target.offset + x * target.dataSize + o] = newData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void downsampleFrom(FullArrayView source)
|
||||
{
|
||||
LodUtil.assertTrue(source.size > this.size && source.size % this.size == 0);
|
||||
int dataPerUnit = source.size / this.size;
|
||||
for (int xOffset = 0; xOffset < this.size; xOffset++)
|
||||
{
|
||||
for (int zOffset = 0; zOffset < this.size; zOffset++)
|
||||
{
|
||||
SingleFullArrayView column = this.get(xOffset, zOffset);
|
||||
column.downsampleFrom(source.subView(dataPerUnit, xOffset * dataPerUnit, zOffset * dataPerUnit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
package com.seibel.lod.core.dataObjects.fullData.accessor;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.lod.core.util.FullDataPointUtil;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class FullDataArrayView implements IFullDataView
|
||||
{
|
||||
protected final FullDataPointIdMap mapping;
|
||||
protected final long[][] dataArrays;
|
||||
|
||||
/** measured in data points */
|
||||
protected final int width;
|
||||
/** measured in data points */
|
||||
protected final int dataWidth;
|
||||
|
||||
protected final int offset;
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
public FullDataArrayView(FullDataPointIdMap mapping, long[][] dataArrays, int width)
|
||||
{
|
||||
if (dataArrays.length != width * width)
|
||||
{
|
||||
throw new IllegalArgumentException("tried constructing dataArrayView with invalid input!");
|
||||
}
|
||||
|
||||
this.dataArrays = dataArrays;
|
||||
this.width = width;
|
||||
this.dataWidth = width;
|
||||
this.mapping = mapping;
|
||||
this.offset = 0;
|
||||
}
|
||||
|
||||
public FullDataArrayView(FullDataArrayView source, int width, int offsetX, int offsetZ)
|
||||
{
|
||||
if (source.width < width || source.width < width + offsetX || source.width < width + offsetZ)
|
||||
{
|
||||
throw new IllegalArgumentException("tried constructing dataArrayView subview with invalid input!");
|
||||
}
|
||||
|
||||
this.dataArrays = source.dataArrays;
|
||||
this.width = width;
|
||||
this.dataWidth = source.dataWidth;
|
||||
this.mapping = source.mapping;
|
||||
this.offset = source.offset + offsetX * this.dataWidth + offsetZ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// methods //
|
||||
//=========//
|
||||
|
||||
@Override
|
||||
public FullDataArrayView subView(int size, int xOffset, int zOffset) { return new FullDataArrayView(this, size, xOffset, zOffset); }
|
||||
|
||||
/** WARNING: This will potentially share the underlying array object! */
|
||||
public void shadowCopyTo(FullDataArrayView target)
|
||||
{
|
||||
if (target.width != this.width)
|
||||
{
|
||||
throw new IllegalArgumentException("Target view must have same size as this view");
|
||||
}
|
||||
|
||||
|
||||
if (target.mapping.equals(this.mapping))
|
||||
{
|
||||
for (int x = 0; x < this.width; x++)
|
||||
{
|
||||
System.arraycopy(this.dataArrays, this.offset + x * this.dataWidth,
|
||||
target.dataArrays, target.offset + x * target.dataWidth, this.width);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int[] remappedIds = target.mapping.mergeAndReturnRemappedEntityIds(this.mapping);
|
||||
for (int x = 0; x < this.width; x++)
|
||||
{
|
||||
for (int z = 0; z < this.width; z++)
|
||||
{
|
||||
long[] sourceData = this.dataArrays[this.offset + x * this.dataWidth + z];
|
||||
long[] newData = new long[sourceData.length];
|
||||
for (int dataPointIndex = 0; dataPointIndex < newData.length; dataPointIndex++)
|
||||
{
|
||||
newData[dataPointIndex] = FullDataPointUtil.remap(remappedIds, sourceData[dataPointIndex]);
|
||||
}
|
||||
|
||||
target.dataArrays[target.offset + x * target.dataWidth + z] = newData;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void downsampleFrom(FullDataArrayView arrayView)
|
||||
{
|
||||
LodUtil.assertTrue(arrayView.width > this.width && arrayView.width % this.width == 0);
|
||||
|
||||
int dataPerUnit = arrayView.width / this.width;
|
||||
for (int xOffset = 0; xOffset < this.width; xOffset++)
|
||||
{
|
||||
for (int zOffset = 0; zOffset < this.width; zOffset++)
|
||||
{
|
||||
SingleFullArrayView column = this.get(xOffset, zOffset);
|
||||
column.downsampleFrom(arrayView.subView(dataPerUnit, xOffset * dataPerUnit, zOffset * dataPerUnit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
|
||||
@Override
|
||||
public FullDataPointIdMap getMapping() { return this.mapping; }
|
||||
|
||||
@Override
|
||||
public SingleFullArrayView get(int index) { return this.get(index / this.width, index % this.width); }
|
||||
@Override
|
||||
public SingleFullArrayView get(int relativeX, int relativeZ) { return new SingleFullArrayView(this.mapping, this.dataArrays, relativeX * this.width + relativeZ + this.offset); }
|
||||
|
||||
@Override
|
||||
public int width() { return this.width; }
|
||||
|
||||
}
|
||||
+8
-3
@@ -9,11 +9,18 @@ public interface IFullDataView
|
||||
{
|
||||
FullDataPointIdMap getMapping();
|
||||
|
||||
/** generally used for iterating through the whole data set */
|
||||
SingleFullArrayView get(int index);
|
||||
SingleFullArrayView get(int x, int z);
|
||||
SingleFullArrayView get(int relativeX, int relativeZ);
|
||||
|
||||
/** measured in full data points */
|
||||
int width();
|
||||
|
||||
IFullDataView subView(int size, int xOffset, int zOffset);
|
||||
|
||||
|
||||
|
||||
|
||||
/** Returns an iterator that goes over each data column */
|
||||
default Iterator<SingleFullArrayView> iterator()
|
||||
{
|
||||
@@ -34,6 +41,4 @@ public interface IFullDataView
|
||||
};
|
||||
}
|
||||
|
||||
IFullDataView subView(int size, int xOffset, int zOffset);
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -37,9 +37,9 @@ public class SingleFullArrayView implements IFullDataView
|
||||
}
|
||||
|
||||
@Override
|
||||
public SingleFullArrayView get(int x, int z)
|
||||
public SingleFullArrayView get(int relativeX, int relativeZ)
|
||||
{
|
||||
if (x != 0 || z != 0)
|
||||
if (relativeX != 0 || relativeZ != 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Only contains 1 column of full data!");
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.seibel.lod.core.dataObjects.fullData.loader;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource;
|
||||
import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
|
||||
@@ -12,14 +12,14 @@ public class FullDataLoader extends AbstractFullDataSourceLoader
|
||||
{
|
||||
public FullDataLoader()
|
||||
{
|
||||
super(FullDataSource.class, FullDataSource.TYPE_ID, new byte[]{FullDataSource.LATEST_VERSION});
|
||||
super(CompleteFullDataSource.class, CompleteFullDataSource.TYPE_ID, new byte[]{ CompleteFullDataSource.LATEST_VERSION});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException
|
||||
{
|
||||
//TODO: Add decompressor here
|
||||
return FullDataSource.loadData(dataFile, bufferedInputStream, level);
|
||||
return CompleteFullDataSource.loadData(dataFile, bufferedInputStream, level);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
package com.seibel.lod.core.dataObjects.fullData.loader;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.SingleChunkFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.SpottyFullDataSource;
|
||||
import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
|
||||
@@ -11,12 +11,12 @@ import java.io.IOException;
|
||||
public class SingleChunkFullDataLoader extends AbstractFullDataSourceLoader
|
||||
{
|
||||
public SingleChunkFullDataLoader() {
|
||||
super(SingleChunkFullDataSource.class, SingleChunkFullDataSource.TYPE_ID, new byte[]{ SingleChunkFullDataSource.LATEST_VERSION});
|
||||
super(SpottyFullDataSource.class, SpottyFullDataSource.TYPE_ID, new byte[]{ SpottyFullDataSource.LATEST_VERSION});
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException
|
||||
{
|
||||
return SingleChunkFullDataSource.loadData(dataFile, bufferedInputStream, level);
|
||||
return SpottyFullDataSource.loadData(dataFile, bufferedInputStream, level);
|
||||
}
|
||||
}
|
||||
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
package com.seibel.lod.core.dataObjects.fullData.sources;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.FullArrayView;
|
||||
import com.seibel.lod.core.pos.DhLodPos;
|
||||
|
||||
public class ChunkSizedFullDataSource extends FullArrayView
|
||||
{
|
||||
public final byte dataDetail;
|
||||
public final int x;
|
||||
public final int z;
|
||||
|
||||
|
||||
|
||||
public ChunkSizedFullDataSource(byte dataDetail, int x, int z)
|
||||
{
|
||||
super(new FullDataPointIdMap(), new long[16 * 16][0], 16);
|
||||
this.dataDetail = dataDetail;
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void setSingleColumn(long[] data, int x, int z)
|
||||
{
|
||||
dataArrays[x * 16 + z] = data;
|
||||
}
|
||||
|
||||
public long nonEmptyCount()
|
||||
{
|
||||
long count = 0;
|
||||
for (long[] data : dataArrays)
|
||||
{
|
||||
if (data.length != 0)
|
||||
count += 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
public long emptyCount() { return 16 * 16 - nonEmptyCount(); }
|
||||
|
||||
public DhLodPos getBBoxLodPos() { return new DhLodPos((byte) (dataDetail + 4), x, z); }
|
||||
|
||||
}
|
||||
+36
-35
@@ -2,7 +2,8 @@ package com.seibel.lod.core.dataObjects.fullData.sources;
|
||||
|
||||
import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||
import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.FullArrayView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.FullDataArrayView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
import com.seibel.lod.core.pos.DhBlockPos2D;
|
||||
@@ -19,13 +20,13 @@ import java.io.*;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
public class CompleteFullDataSource extends FullDataArrayView implements IFullDataSource
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static final byte SECTION_SIZE_OFFSET = 6;
|
||||
public static final int SECTION_SIZE = 1 << SECTION_SIZE_OFFSET;
|
||||
public static final byte LATEST_VERSION = 0;
|
||||
public static final long TYPE_ID = "FullDataSource".hashCode();
|
||||
public static final long TYPE_ID = "CompleteFullDataSource".hashCode();
|
||||
|
||||
private final DhSectionPos sectionPos;
|
||||
private boolean isEmpty = true;
|
||||
@@ -33,13 +34,13 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
|
||||
|
||||
// TODO why is this protected?
|
||||
protected FullDataSource(DhSectionPos sectionPos)
|
||||
protected CompleteFullDataSource(DhSectionPos sectionPos)
|
||||
{
|
||||
super(new FullDataPointIdMap(), new long[SECTION_SIZE*SECTION_SIZE][0], SECTION_SIZE);
|
||||
this.sectionPos = sectionPos;
|
||||
}
|
||||
|
||||
public FullDataSource(DhSectionPos pos, FullDataPointIdMap mapping, long[][] data)
|
||||
public CompleteFullDataSource(DhSectionPos pos, FullDataPointIdMap mapping, long[][] data)
|
||||
{
|
||||
super(mapping, data, SECTION_SIZE);
|
||||
LodUtil.assertTrue(data.length == SECTION_SIZE * SECTION_SIZE);
|
||||
@@ -52,7 +53,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
@Override
|
||||
public DhSectionPos getSectionPos() { return this.sectionPos; }
|
||||
@Override
|
||||
public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); }
|
||||
public byte getDataDetailLevel() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); }
|
||||
|
||||
@Override
|
||||
public byte getDataVersion() { return LATEST_VERSION; }
|
||||
@@ -62,19 +63,19 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
public EDhApiWorldGenerationStep getWorldGenStep() { return EDhApiWorldGenerationStep.EMPTY; }
|
||||
|
||||
@Override
|
||||
public SingleFullArrayView tryGet(int x, int z) { return this.get(x, z); }
|
||||
public SingleFullArrayView tryGet(int relativeX, int relativeZ) { return this.get(relativeX, relativeZ); }
|
||||
|
||||
@Override
|
||||
public void update(ChunkSizedFullDataSource data)
|
||||
public void update(ChunkSizedFullDataView chunkDataView)
|
||||
{
|
||||
LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(data.getBBoxLodPos()));
|
||||
if (data.dataDetail == 0 && this.getDataDetail() == 0)
|
||||
LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(chunkDataView.getLodPos()));
|
||||
if (this.getDataDetailLevel() == 0)
|
||||
{
|
||||
DhBlockPos2D chunkBlockPos = new DhBlockPos2D(data.x * 16, data.z * 16);
|
||||
DhBlockPos2D chunkBlockPos = new DhBlockPos2D(chunkDataView.pos.x * 16, chunkDataView.pos.z * 16);
|
||||
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;
|
||||
data.shadowCopyTo(this.subView(16, blockOffset.x, blockOffset.z));
|
||||
chunkDataView.shadowCopyTo(this.subView(16, blockOffset.x, blockOffset.z));
|
||||
{ // DEBUG ASSERTION
|
||||
for (int x = 0; x < 16; x++)
|
||||
{
|
||||
@@ -86,12 +87,12 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.dataDetail == 0 && this.getDataDetail() < 4)
|
||||
else if (this.getDataDetailLevel() < 4)
|
||||
{
|
||||
int dataPerFull = 1 << this.getDataDetail();
|
||||
int dataPerFull = 1 << this.getDataDetailLevel();
|
||||
int fullSize = 16 / dataPerFull;
|
||||
DhLodPos dataOffset = data.getBBoxLodPos().getCornerLodPos(this.getDataDetail());
|
||||
DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail());
|
||||
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);
|
||||
@@ -101,26 +102,26 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
for (int oz = 0; oz < fullSize; oz++)
|
||||
{
|
||||
SingleFullArrayView column = this.get(ox + offsetX, oz + offsetZ);
|
||||
column.downsampleFrom(data.subView(dataPerFull, ox * dataPerFull, oz * dataPerFull));
|
||||
column.downsampleFrom(chunkDataView.subView(dataPerFull, ox * dataPerFull, oz * dataPerFull));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (data.dataDetail == 0 && this.getDataDetail() >= 4)
|
||||
else if (this.getDataDetailLevel() >= 4)
|
||||
{
|
||||
//FIXME: TEMPORARY
|
||||
int chunkPerFull = 1 << (this.getDataDetail() - 4);
|
||||
if (data.x % chunkPerFull != 0 || data.z % chunkPerFull != 0)
|
||||
int chunkPerFull = 1 << (this.getDataDetailLevel() - 4);
|
||||
if (chunkDataView.pos.x % chunkPerFull != 0 || chunkDataView.pos.z % chunkPerFull != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail());
|
||||
DhLodPos dataOffset = data.getBBoxLodPos().convertToDetailLevel(this.getDataDetail());
|
||||
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;
|
||||
data.get(0, 0).deepCopyTo(this.get(offsetX, offsetZ));
|
||||
chunkDataView.get(0, 0).deepCopyTo(this.get(offsetX, offsetZ));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -136,7 +137,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
|
||||
|
||||
|
||||
public static FullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException
|
||||
public static CompleteFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException
|
||||
{
|
||||
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream); // DO NOT CLOSE
|
||||
|
||||
@@ -164,7 +165,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
if (end == IFullDataSource.NO_DATA_FLAG_BYTE)
|
||||
{
|
||||
// Section is empty
|
||||
return new FullDataSource(dataFile.pos);
|
||||
return new CompleteFullDataSource(dataFile.pos);
|
||||
}
|
||||
// Non-empty section
|
||||
if (end != IFullDataSource.DATA_GUARD_BYTE)
|
||||
@@ -211,7 +212,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
throw new IOException("invalid id mapping end guard");
|
||||
}
|
||||
|
||||
return new FullDataSource(dataFile.pos, mapping, data);
|
||||
return new CompleteFullDataSource(dataFile.pos, mapping, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,8 +221,8 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream); // DO NOT CLOSE
|
||||
|
||||
|
||||
dataOutputStream.writeInt(this.getDataDetail());
|
||||
dataOutputStream.writeInt(this.size);
|
||||
dataOutputStream.writeInt(this.getDataDetailLevel());
|
||||
dataOutputStream.writeInt(this.width);
|
||||
dataOutputStream.writeInt(level.getMinY());
|
||||
if (this.isEmpty)
|
||||
{
|
||||
@@ -231,9 +232,9 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
dataOutputStream.writeInt(0xFFFFFFFF);
|
||||
|
||||
// Data array length
|
||||
for (int x = 0; x < this.size; x++)
|
||||
for (int x = 0; x < this.width; x++)
|
||||
{
|
||||
for (int z = 0; z < this.size; z++)
|
||||
for (int z = 0; z < this.width; z++)
|
||||
{
|
||||
dataOutputStream.writeInt(this.get(x, z).getSingleLength());
|
||||
}
|
||||
@@ -241,9 +242,9 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
|
||||
// Data array content (only on non-empty columns)
|
||||
dataOutputStream.writeInt(0xFFFFFFFF);
|
||||
for (int x = 0; x < this.size; x++)
|
||||
for (int x = 0; x < this.width; x++)
|
||||
{
|
||||
for (int z = 0; z < this.size; z++)
|
||||
for (int z = 0; z < this.width; z++)
|
||||
{
|
||||
SingleFullArrayView column = this.get(x, z);
|
||||
if (!column.doesItExist())
|
||||
@@ -264,7 +265,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
}
|
||||
|
||||
|
||||
public static FullDataSource createEmpty(DhSectionPos pos) { return new FullDataSource(pos); }
|
||||
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)
|
||||
@@ -298,7 +299,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
}
|
||||
}
|
||||
|
||||
public void writeFromLower(FullDataSource subData)
|
||||
public void writeFromLower(CompleteFullDataSource subData)
|
||||
{
|
||||
LodUtil.assertTrue(this.sectionPos.overlaps(subData.sectionPos));
|
||||
LodUtil.assertTrue(subData.sectionPos.sectionDetailLevel < this.sectionPos.sectionDetailLevel);
|
||||
@@ -306,7 +307,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource
|
||||
return;
|
||||
DhSectionPos lowerSectPos = subData.sectionPos;
|
||||
byte detailDiff = (byte) (this.sectionPos.sectionDetailLevel - subData.sectionPos.sectionDetailLevel);
|
||||
byte targetDataDetail = this.getDataDetail();
|
||||
byte targetDataDetail = this.getDataDetailLevel();
|
||||
DhLodPos minDataPos = this.sectionPos.getCorner(targetDataDetail);
|
||||
if (detailDiff <= SECTION_SIZE_OFFSET)
|
||||
{
|
||||
+5
-5
@@ -2,8 +2,8 @@ package com.seibel.lod.core.dataObjects.fullData.sources;
|
||||
|
||||
import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||
import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
@@ -13,7 +13,7 @@ import java.io.IOException;
|
||||
|
||||
// TODO make into an abstract class so the read(stream) method can be used as a constructor
|
||||
// TODO validate how we know which file to use when (probably, TYPE_ID)
|
||||
// TODO merge with FullArrayView and IFullDataView
|
||||
// TODO merge with FullDataArrayView and IFullDataView
|
||||
public interface IFullDataSource
|
||||
{
|
||||
/**
|
||||
@@ -28,11 +28,11 @@ public interface IFullDataSource
|
||||
|
||||
public abstract DhSectionPos getSectionPos();
|
||||
|
||||
public abstract byte getDataDetail();
|
||||
public abstract byte getDataDetailLevel();
|
||||
public abstract byte getDataVersion();
|
||||
public abstract EDhApiWorldGenerationStep getWorldGenStep();
|
||||
|
||||
public abstract void update(ChunkSizedFullDataSource data);
|
||||
public abstract void update(ChunkSizedFullDataView data);
|
||||
|
||||
public abstract boolean isEmpty();
|
||||
|
||||
@@ -69,7 +69,7 @@ public interface IFullDataSource
|
||||
* Attempts to get the data column for the given relative x and z position.
|
||||
* @return null if the data doesn't exist
|
||||
*/
|
||||
public abstract SingleFullArrayView tryGet(int x, int z);
|
||||
public abstract SingleFullArrayView tryGet(int relativeX, int relativeZ);
|
||||
|
||||
public abstract FullDataPointIdMap getMapping();
|
||||
|
||||
|
||||
+6
-1
@@ -4,6 +4,11 @@ public interface IIncompleteFullDataSource extends IFullDataSource
|
||||
{
|
||||
void sampleFrom(IFullDataSource fullDataSource);
|
||||
|
||||
IFullDataSource trySelfPromote();
|
||||
/**
|
||||
* Attempts to convert this {@link IIncompleteFullDataSource} into a {@link CompleteFullDataSource}.
|
||||
*
|
||||
* @return this if the promotion failed, a new {@link CompleteFullDataSource} if successful.
|
||||
*/
|
||||
IFullDataSource tryPromotingToCompleteDataSource();
|
||||
|
||||
}
|
||||
|
||||
+49
-48
@@ -2,7 +2,8 @@ package com.seibel.lod.core.dataObjects.fullData.sources;
|
||||
|
||||
import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||
import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.FullArrayView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.FullDataArrayView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView;
|
||||
import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
@@ -18,7 +19,7 @@ import java.util.BitSet;
|
||||
|
||||
/**
|
||||
* Handles full data with the detail level {@link SparseFullDataSource#SPARSE_UNIT_DETAIL}.
|
||||
* In other words, this is the middle ground between {@link SingleChunkFullDataSource} and {@link FullDataSource}
|
||||
* In other words, this is the middle ground between {@link SpottyFullDataSource} and {@link CompleteFullDataSource}
|
||||
*/
|
||||
public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
{
|
||||
@@ -42,7 +43,7 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
|
||||
protected final FullDataPointIdMap mapping;
|
||||
private final DhSectionPos sectionPos;
|
||||
private final FullArrayView[] sparseData;
|
||||
private final FullDataArrayView[] sparseData;
|
||||
private final DhLodPos chunkPos;
|
||||
|
||||
public final int chunks;
|
||||
@@ -63,12 +64,12 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
this.sectionPos = sectionPos;
|
||||
this.chunks = 1 << (byte) (sectionPos.sectionDetailLevel - SPARSE_UNIT_DETAIL);
|
||||
this.dataPerChunk = SECTION_SIZE / this.chunks;
|
||||
this.sparseData = new FullArrayView[this.chunks * this.chunks];
|
||||
this.sparseData = new FullDataArrayView[this.chunks * this.chunks];
|
||||
this.chunkPos = sectionPos.getCorner(SPARSE_UNIT_DETAIL);
|
||||
this.mapping = new FullDataPointIdMap();
|
||||
}
|
||||
|
||||
protected SparseFullDataSource(DhSectionPos sectionPos, FullDataPointIdMap mapping, FullArrayView[] data)
|
||||
protected SparseFullDataSource(DhSectionPos sectionPos, FullDataPointIdMap mapping, FullDataArrayView[] data)
|
||||
{
|
||||
LodUtil.assertTrue(sectionPos.sectionDetailLevel > SPARSE_UNIT_DETAIL);
|
||||
LodUtil.assertTrue(sectionPos.sectionDetailLevel <= MAX_SECTION_DETAIL);
|
||||
@@ -91,7 +92,7 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
@Override
|
||||
public DhSectionPos getSectionPos() { return this.sectionPos; }
|
||||
@Override
|
||||
public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); }
|
||||
public byte getDataDetailLevel() { return (byte) (this.sectionPos.sectionDetailLevel - SECTION_SIZE_OFFSET); }
|
||||
|
||||
@Override
|
||||
public byte getDataVersion() { return LATEST_VERSION; }
|
||||
@@ -113,19 +114,13 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
|
||||
|
||||
@Override
|
||||
public void update(ChunkSizedFullDataSource data)
|
||||
public void update(ChunkSizedFullDataView chunkDataView)
|
||||
{
|
||||
if (data.dataDetail != 0)
|
||||
int arrayOffset = this.calculateOffset(chunkDataView.pos.x, chunkDataView.pos.z);
|
||||
FullDataArrayView newArray = new FullDataArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk);
|
||||
if (this.getDataDetailLevel() == chunkDataView.detailLevel)
|
||||
{
|
||||
//TODO: Disable the throw and instead just ignore the data.
|
||||
throw new IllegalArgumentException("SparseFullDataSource 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);
|
||||
chunkDataView.shadowCopyTo(newArray);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -137,10 +132,11 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
for (int zOffset = 0; zOffset < count; zOffset++)
|
||||
{
|
||||
SingleFullArrayView column = newArray.get(xOffset, zOffset);
|
||||
column.downsampleFrom(data.subView(dataPerCount, xOffset * dataPerCount, zOffset * dataPerCount));
|
||||
column.downsampleFrom(chunkDataView.subView(dataPerCount, xOffset * dataPerCount, zOffset * dataPerCount));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.isEmpty = false;
|
||||
this.sparseData[arrayOffset] = newArray;
|
||||
}
|
||||
@@ -165,9 +161,9 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
{
|
||||
this.sampleFrom((SparseFullDataSource) source);
|
||||
}
|
||||
else if (source instanceof FullDataSource)
|
||||
else if (source instanceof CompleteFullDataSource)
|
||||
{
|
||||
this.sampleFrom((FullDataSource) source);
|
||||
this.sampleFrom((CompleteFullDataSource) source);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -190,17 +186,17 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
{
|
||||
for (int zOffset = 0; zOffset < sparseSource.chunks; zOffset++)
|
||||
{
|
||||
FullArrayView sourceChunk = sparseSource.sparseData[xOffset * sparseSource.chunks + zOffset];
|
||||
FullDataArrayView sourceChunk = sparseSource.sparseData[xOffset * sparseSource.chunks + zOffset];
|
||||
if (sourceChunk != null)
|
||||
{
|
||||
FullArrayView buff = new FullArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk);
|
||||
FullDataArrayView buff = new FullDataArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk);
|
||||
buff.downsampleFrom(sourceChunk);
|
||||
this.sparseData[(xOffset + offsetX) * this.chunks + (zOffset + offsetZ)] = buff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void sampleFrom(FullDataSource fullSource)
|
||||
private void sampleFrom(CompleteFullDataSource fullSource)
|
||||
{
|
||||
DhSectionPos pos = fullSource.getSectionPos();
|
||||
this.isEmpty = false;
|
||||
@@ -208,8 +204,8 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
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 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);
|
||||
@@ -218,8 +214,8 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
{
|
||||
for (int zOffset = 0; zOffset < coveredChunks; zOffset++)
|
||||
{
|
||||
FullArrayView sourceChunk = fullSource.subView(sourceDataPerChunk, xOffset * sourceDataPerChunk, zOffset * sourceDataPerChunk);
|
||||
FullArrayView buff = new FullArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk);
|
||||
FullDataArrayView sourceChunk = fullSource.subView(sourceDataPerChunk, xOffset * sourceDataPerChunk, zOffset * sourceDataPerChunk);
|
||||
FullDataArrayView buff = new FullDataArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk);
|
||||
buff.downsampleFrom(sourceChunk);
|
||||
this.sparseData[(xOffset + offsetX) * this.chunks + (zOffset + offsetZ)] = buff;
|
||||
}
|
||||
@@ -238,7 +234,7 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream);
|
||||
|
||||
|
||||
dataOutputStream.writeShort(this.getDataDetail());
|
||||
dataOutputStream.writeShort(this.getDataDetailLevel());
|
||||
dataOutputStream.writeShort(SPARSE_UNIT_DETAIL);
|
||||
dataOutputStream.writeInt(SECTION_SIZE);
|
||||
dataOutputStream.writeInt(level.getMinY());
|
||||
@@ -266,7 +262,7 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
i = dataArrayIndexHasData.nextSetBit(i+1))
|
||||
{
|
||||
// column data length
|
||||
FullArrayView array = this.sparseData[i];
|
||||
FullDataArrayView array = this.sparseData[i];
|
||||
LodUtil.assertTrue(array != null);
|
||||
for (int x = 0; x < array.width(); x++)
|
||||
{
|
||||
@@ -451,12 +447,12 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
throw new IOException("invalid id mapping end guard");
|
||||
}
|
||||
|
||||
FullArrayView[] fullDataArrays = new FullArrayView[chunks * chunks];
|
||||
FullDataArrayView[] fullDataArrays = new FullDataArrayView[chunks * chunks];
|
||||
for (int i = 0; i < rawFullDataArrays.length; i++)
|
||||
{
|
||||
if (rawFullDataArrays[i] != null)
|
||||
{
|
||||
fullDataArrays[i] = new FullArrayView(mapping, rawFullDataArrays[i], dataPointsPerChunk);
|
||||
fullDataArrays[i] = new FullDataArrayView(mapping, rawFullDataArrays[i], dataPointsPerChunk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,53 +462,58 @@ public class SparseFullDataSource implements IIncompleteFullDataSource
|
||||
|
||||
|
||||
|
||||
private void applyToFullDataSource(FullDataSource dataSource)
|
||||
private void applyToFullDataSource(CompleteFullDataSource dataSource)
|
||||
{
|
||||
LodUtil.assertTrue(dataSource.getSectionPos().equals(this.sectionPos));
|
||||
LodUtil.assertTrue(dataSource.getDataDetail() == this.getDataDetail());
|
||||
LodUtil.assertTrue(dataSource.getDataDetailLevel() == this.getDataDetailLevel());
|
||||
for (int x = 0; x < this.chunks; x++)
|
||||
{
|
||||
for (int z = 0; z < this.chunks; z++)
|
||||
{
|
||||
FullArrayView array = this.sparseData[x * this.chunks + z];
|
||||
FullDataArrayView array = this.sparseData[x * this.chunks + z];
|
||||
if (array == null)
|
||||
continue;
|
||||
|
||||
// Otherwise, apply data to dataSource
|
||||
dataSource.markNotEmpty();
|
||||
FullArrayView view = dataSource.subView(this.dataPerChunk, x * this.dataPerChunk, z * this.dataPerChunk);
|
||||
FullDataArrayView view = dataSource.subView(this.dataPerChunk, x * this.dataPerChunk, z * this.dataPerChunk);
|
||||
array.shadowCopyTo(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public IFullDataSource trySelfPromote()
|
||||
public IFullDataSource tryPromotingToCompleteDataSource()
|
||||
{
|
||||
if (this.isEmpty)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
for (FullArrayView array : this.sparseData)
|
||||
// promotion can only succeed if every data column is present
|
||||
for (FullDataArrayView array : this.sparseData)
|
||||
{
|
||||
if (array == null) return this;
|
||||
}
|
||||
FullDataSource newSource = FullDataSource.createEmpty(this.sectionPos);
|
||||
this.applyToFullDataSource(newSource);
|
||||
return newSource;
|
||||
if (array == null)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
CompleteFullDataSource fullDataSource = CompleteFullDataSource.createEmpty(this.sectionPos);
|
||||
this.applyToFullDataSource(fullDataSource);
|
||||
return fullDataSource;
|
||||
}
|
||||
|
||||
public SingleFullArrayView tryGet(int x, int z)
|
||||
public SingleFullArrayView tryGet(int relativeX, int relativeZ)
|
||||
{
|
||||
LodUtil.assertTrue(x>=0 && x<SECTION_SIZE && z>=0 && z<SECTION_SIZE);
|
||||
int chunkX = x / this.dataPerChunk;
|
||||
int chunkZ = z / this.dataPerChunk;
|
||||
FullArrayView chunk = this.sparseData[chunkX * this.chunks + chunkZ];
|
||||
LodUtil.assertTrue(relativeX >=0 && relativeX <SECTION_SIZE && relativeZ >=0 && relativeZ <SECTION_SIZE);
|
||||
int chunkX = relativeX / this.dataPerChunk;
|
||||
int chunkZ = relativeZ / this.dataPerChunk;
|
||||
FullDataArrayView chunk = this.sparseData[chunkX * this.chunks + chunkZ];
|
||||
if (chunk == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return chunk.get(x % this.dataPerChunk, z % this.dataPerChunk);
|
||||
return chunk.get(relativeX % this.dataPerChunk, relativeZ % this.dataPerChunk);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+46
-41
@@ -2,7 +2,8 @@ package com.seibel.lod.core.dataObjects.fullData.sources;
|
||||
|
||||
import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||
import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.FullArrayView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.FullDataArrayView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView;
|
||||
import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
@@ -16,15 +17,16 @@ import java.io.*;
|
||||
import java.util.BitSet;
|
||||
|
||||
/**
|
||||
* 1 chunk of full data (formerly SpottyDataSource)
|
||||
* more data than sparse, less than complete.
|
||||
* TODO there has to be a better way to name these
|
||||
*/
|
||||
public class SingleChunkFullDataSource extends FullArrayView implements IIncompleteFullDataSource
|
||||
public class SpottyFullDataSource extends FullDataArrayView implements IIncompleteFullDataSource
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static final byte SECTION_SIZE_OFFSET = 6;
|
||||
public static final int SECTION_SIZE = 1 << SECTION_SIZE_OFFSET;
|
||||
public static final byte LATEST_VERSION = 0;
|
||||
public static final long TYPE_ID = "SingleChunkFullDataSource".hashCode();
|
||||
public static final long TYPE_ID = "SpottyFullDataSource".hashCode();
|
||||
|
||||
private final DhSectionPos sectionPos;
|
||||
private final BitSet isColumnNotEmpty;
|
||||
@@ -38,7 +40,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
// constructors //
|
||||
//==============//
|
||||
|
||||
protected SingleChunkFullDataSource(DhSectionPos sectionPos)
|
||||
protected SpottyFullDataSource(DhSectionPos sectionPos)
|
||||
{
|
||||
super(new FullDataPointIdMap(), new long[SECTION_SIZE*SECTION_SIZE][0], SECTION_SIZE);
|
||||
LodUtil.assertTrue(sectionPos.sectionDetailLevel > SparseFullDataSource.MAX_SECTION_DETAIL);
|
||||
@@ -48,7 +50,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
this.worldGenStep = EDhApiWorldGenerationStep.EMPTY;
|
||||
}
|
||||
|
||||
private SingleChunkFullDataSource(DhSectionPos pos, FullDataPointIdMap mapping, EDhApiWorldGenerationStep worldGenStep, BitSet isColumnNotEmpty, long[][] data)
|
||||
private SpottyFullDataSource(DhSectionPos pos, FullDataPointIdMap mapping, EDhApiWorldGenerationStep worldGenStep, BitSet isColumnNotEmpty, long[][] data)
|
||||
{
|
||||
super(mapping, data, SECTION_SIZE);
|
||||
LodUtil.assertTrue(data.length == SECTION_SIZE*SECTION_SIZE);
|
||||
@@ -59,7 +61,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
this.isEmpty = false;
|
||||
}
|
||||
|
||||
public static SingleChunkFullDataSource createEmpty(DhSectionPos pos) { return new SingleChunkFullDataSource(pos); }
|
||||
public static SpottyFullDataSource createEmpty(DhSectionPos pos) { return new SpottyFullDataSource(pos); }
|
||||
|
||||
|
||||
|
||||
@@ -67,7 +69,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
// file handling //
|
||||
//===============//
|
||||
|
||||
public static SingleChunkFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException
|
||||
public static SpottyFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException
|
||||
{
|
||||
DataInputStream dataInputStream = new DataInputStream(bufferedInputStream); // DO NOT CLOSE
|
||||
|
||||
@@ -91,7 +93,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
if (end == IFullDataSource.NO_DATA_FLAG_BYTE)
|
||||
{
|
||||
// Section is empty
|
||||
return new SingleChunkFullDataSource(dataFile.pos);
|
||||
return new SpottyFullDataSource(dataFile.pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +162,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
|
||||
|
||||
|
||||
return new SingleChunkFullDataSource(dataFile.pos, mapping, worldGenStep, isColumnNotEmpty, data);
|
||||
return new SpottyFullDataSource(dataFile.pos, mapping, worldGenStep, isColumnNotEmpty, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,8 +171,8 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream); // DO NOT CLOSE
|
||||
|
||||
|
||||
dataOutputStream.writeInt(this.getDataDetail());
|
||||
dataOutputStream.writeInt(this.size);
|
||||
dataOutputStream.writeInt(this.getDataDetailLevel());
|
||||
dataOutputStream.writeInt(this.width);
|
||||
dataOutputStream.writeInt(level.getMinY());
|
||||
if (this.isEmpty)
|
||||
{
|
||||
@@ -216,18 +218,21 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
//===============//
|
||||
|
||||
@Override
|
||||
public void update(ChunkSizedFullDataSource data)
|
||||
public void update(ChunkSizedFullDataView data)
|
||||
{
|
||||
LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(data.getBBoxLodPos()));
|
||||
LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(data.getLodPos()));
|
||||
|
||||
if (data.dataDetail == 0 && this.getDataDetail() >= 4)
|
||||
if (this.getDataDetailLevel() >= 4)
|
||||
{
|
||||
//FIXME: TEMPORARY
|
||||
int chunkPerFull = 1 << (this.getDataDetail() - 4);
|
||||
if (data.x % chunkPerFull != 0 || data.z % chunkPerFull != 0)
|
||||
int chunkPerFull = 1 << (this.getDataDetailLevel() - 4);
|
||||
if (data.pos.x % chunkPerFull != 0 || data.pos.z % chunkPerFull != 0)
|
||||
{
|
||||
return;
|
||||
DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail());
|
||||
DhLodPos dataOffset = data.getBBoxLodPos().convertToDetailLevel(this.getDataDetail());
|
||||
}
|
||||
|
||||
DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetailLevel());
|
||||
DhLodPos dataOffset = data.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);
|
||||
@@ -255,9 +260,9 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
{
|
||||
this.sampleFrom((SparseFullDataSource) source);
|
||||
}
|
||||
else if (source instanceof FullDataSource)
|
||||
else if (source instanceof CompleteFullDataSource)
|
||||
{
|
||||
this.sampleFrom((FullDataSource) source);
|
||||
this.sampleFrom((CompleteFullDataSource) source);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -270,15 +275,15 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
DhSectionPos pos = sparseSource.getSectionPos();
|
||||
this.isEmpty = false;
|
||||
|
||||
if (this.getDataDetail() > this.sectionPos.sectionDetailLevel)
|
||||
if (this.getDataDetailLevel() > this.sectionPos.sectionDetailLevel)
|
||||
{
|
||||
DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail());
|
||||
DhLodPos dataPos = pos.getCorner(this.getDataDetail());
|
||||
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;
|
||||
LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE);
|
||||
int chunksPerData = 1 << (this.getDataDetail() - SparseFullDataSource.SPARSE_UNIT_DETAIL);
|
||||
int dataSpan = this.sectionPos.getWidth(this.getDataDetail()).numberOfLodSectionsWide;
|
||||
int chunksPerData = 1 << (this.getDataDetailLevel() - SparseFullDataSource.SPARSE_UNIT_DETAIL);
|
||||
int dataSpan = this.sectionPos.getWidth(this.getDataDetailLevel()).numberOfLodSectionsWide;
|
||||
|
||||
for (int xOffset = 0; xOffset < dataSpan; xOffset++)
|
||||
{
|
||||
@@ -302,8 +307,8 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
int lowerSectionsPerData = this.sectionPos.getWidth(dataPos.detailLevel).numberOfLodSectionsWide;
|
||||
if (dataPos.x % lowerSectionsPerData != 0 || dataPos.z % lowerSectionsPerData != 0) return;
|
||||
|
||||
DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail());
|
||||
dataPos = dataPos.convertToDetailLevel(this.getDataDetail());
|
||||
DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel());
|
||||
dataPos = dataPos.convertToDetailLevel(this.getDataDetailLevel());
|
||||
int offsetX = dataPos.x - basePos.x;
|
||||
int offsetZ = dataPos.z - basePos.z;
|
||||
SingleFullArrayView column = sparseSource.tryGet(0, 0);
|
||||
@@ -314,19 +319,19 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
}
|
||||
}
|
||||
|
||||
private void sampleFrom(FullDataSource fullSource)
|
||||
private void sampleFrom(CompleteFullDataSource fullSource)
|
||||
{
|
||||
DhSectionPos pos = fullSource.getSectionPos();
|
||||
this.isEmpty = false;
|
||||
this.downsampleFrom(fullSource);
|
||||
|
||||
if (this.getDataDetail() > this.sectionPos.sectionDetailLevel)
|
||||
if (this.getDataDetailLevel() > this.sectionPos.sectionDetailLevel)
|
||||
{
|
||||
DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail());
|
||||
DhLodPos dataPos = pos.getCorner(this.getDataDetail());
|
||||
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.getDataDetail()).numberOfLodSectionsWide;
|
||||
int dataSpan = this.sectionPos.getWidth(this.getDataDetailLevel()).numberOfLodSectionsWide;
|
||||
|
||||
for (int xOffset = 0; xOffset < dataSpan; xOffset++)
|
||||
{
|
||||
@@ -345,8 +350,8 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
return;
|
||||
}
|
||||
|
||||
DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail());
|
||||
dataPos = dataPos.convertToDetailLevel(this.getDataDetail());
|
||||
DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel());
|
||||
dataPos = dataPos.convertToDetailLevel(this.getDataDetailLevel());
|
||||
int offsetX = dataPos.x - basePos.x;
|
||||
int offsetZ = dataPos.z - basePos.z;
|
||||
this.isColumnNotEmpty.set(offsetX * SECTION_SIZE + offsetZ, true);
|
||||
@@ -355,19 +360,19 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
}
|
||||
|
||||
@Override
|
||||
public IFullDataSource trySelfPromote()
|
||||
public IFullDataSource tryPromotingToCompleteDataSource()
|
||||
{
|
||||
// promotion can only be completed if every column has data
|
||||
if (this.isEmpty)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
if (this.isColumnNotEmpty.cardinality() != SECTION_SIZE * SECTION_SIZE)
|
||||
else if (this.isColumnNotEmpty.cardinality() != SECTION_SIZE * SECTION_SIZE)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
|
||||
return new FullDataSource(this.sectionPos, this.mapping, this.dataArrays);
|
||||
return new CompleteFullDataSource(this.sectionPos, this.mapping, this.dataArrays);
|
||||
}
|
||||
|
||||
|
||||
@@ -377,7 +382,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
//
|
||||
|
||||
@Override
|
||||
public SingleFullArrayView tryGet(int x, int z) { return this.isColumnNotEmpty.get(x * SECTION_SIZE + z) ? this.get(x, z) : null; }
|
||||
public SingleFullArrayView tryGet(int relativeX, int relativeZ) { return this.isColumnNotEmpty.get(relativeX * SECTION_SIZE + relativeZ) ? this.get(relativeX, relativeZ) : null; }
|
||||
|
||||
|
||||
|
||||
@@ -388,7 +393,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl
|
||||
@Override
|
||||
public DhSectionPos getSectionPos() { return this.sectionPos; }
|
||||
@Override
|
||||
public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); }
|
||||
public byte getDataDetailLevel() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); }
|
||||
@Override
|
||||
public byte getDataVersion() { return LATEST_VERSION; }
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.seibel.lod.core.dataObjects.render;
|
||||
|
||||
import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenerationStep;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IIncompleteFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.transformers.FullToColumnTransformer;
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
@@ -58,16 +58,16 @@ public class ColumnRenderLoader
|
||||
}
|
||||
}
|
||||
|
||||
/** @throws InterruptedException see {@link FullToColumnTransformer#transformFullDataToColumnData(IDhClientLevel, FullDataSource) FullToColumnTransformer#transformFullDataToColumnData} for documentation */
|
||||
public ColumnRenderSource createRenderSource(IFullDataSource dataSource, IDhClientLevel level) throws InterruptedException
|
||||
/** @throws InterruptedException see {@link FullToColumnTransformer#transformFullDataToColumnData(IDhClientLevel, CompleteFullDataSource) FullToColumnTransformer#transformFullDataToColumnData} for documentation */
|
||||
public ColumnRenderSource createRenderSource(IFullDataSource fullDataSource, IDhClientLevel level) throws InterruptedException
|
||||
{
|
||||
if (dataSource instanceof FullDataSource)
|
||||
if (fullDataSource instanceof CompleteFullDataSource)
|
||||
{
|
||||
return FullToColumnTransformer.transformFullDataToColumnData(level, (FullDataSource) dataSource);
|
||||
return FullToColumnTransformer.transformFullDataToColumnData(level, (CompleteFullDataSource) fullDataSource);
|
||||
}
|
||||
else if (dataSource instanceof IIncompleteFullDataSource)
|
||||
else if (fullDataSource instanceof IIncompleteFullDataSource)
|
||||
{
|
||||
return FullToColumnTransformer.transformIncompleteDataToColumnData(level, (IIncompleteFullDataSource) dataSource);
|
||||
return FullToColumnTransformer.transformIncompleteDataToColumnData(level, (IIncompleteFullDataSource) fullDataSource);
|
||||
}
|
||||
|
||||
LodUtil.assertNotReach();
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.seibel.lod.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.lod.core.dataObjects.render.columnViews.ColumnQuadView;
|
||||
import com.seibel.lod.core.dataObjects.render.columnViews.IColumnDataView;
|
||||
import com.seibel.lod.core.dataObjects.render.bufferBuilding.ColumnRenderBuffer;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.transformers.FullToColumnTransformer;
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
@@ -296,7 +296,7 @@ public class ColumnRenderSource
|
||||
}
|
||||
}
|
||||
|
||||
public void fastWrite(ChunkSizedFullDataSource chunkData, IDhClientLevel level)
|
||||
public void fastWrite(ChunkSizedFullDataView chunkData, IDhClientLevel level)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
+9
-9
@@ -3,7 +3,7 @@ package com.seibel.lod.core.dataObjects.transformers;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.config.Config;
|
||||
import com.seibel.lod.core.logging.ConfigBasedLogger;
|
||||
import com.seibel.lod.core.pos.DhChunkPos;
|
||||
@@ -25,9 +25,9 @@ public class ChunkToLodBuilder
|
||||
private static class Task
|
||||
{
|
||||
final DhChunkPos chunkPos;
|
||||
final CompletableFuture<ChunkSizedFullDataSource> future;
|
||||
final CompletableFuture<ChunkSizedFullDataView> future;
|
||||
|
||||
Task(DhChunkPos chunkPos, CompletableFuture<ChunkSizedFullDataSource> future)
|
||||
Task(DhChunkPos chunkPos, CompletableFuture<ChunkSizedFullDataView> future)
|
||||
{
|
||||
this.chunkPos = chunkPos;
|
||||
this.future = future;
|
||||
@@ -44,14 +44,14 @@ public class ChunkToLodBuilder
|
||||
|
||||
|
||||
|
||||
public CompletableFuture<ChunkSizedFullDataSource> tryGenerateData(IChunkWrapper chunk)
|
||||
public CompletableFuture<ChunkSizedFullDataView> tryGenerateData(IChunkWrapper chunkWrapper)
|
||||
{
|
||||
if (chunk == null)
|
||||
if (chunkWrapper == null)
|
||||
{
|
||||
throw new NullPointerException("ChunkWrapper cannot be null!");
|
||||
}
|
||||
|
||||
IChunkWrapper oldChunk = this.latestChunkToBuild.put(chunk.getChunkPos(), chunk); // an Exchange operation
|
||||
IChunkWrapper oldChunk = this.latestChunkToBuild.put(chunkWrapper.getChunkPos(), chunkWrapper); // an Exchange operation
|
||||
// If there's old chunk, that means we just replaced an unprocessed old request on generating data on this pos.
|
||||
// if so, we can just return null to signal this, as the old request's future will instead be the proper one
|
||||
// that will return the latest generated data.
|
||||
@@ -61,8 +61,8 @@ public class ChunkToLodBuilder
|
||||
}
|
||||
|
||||
// Otherwise, it means we're the first to do so. Let's submit our task to this entry.
|
||||
CompletableFuture<ChunkSizedFullDataSource> future = new CompletableFuture<>();
|
||||
this.taskToBuild.addLast(new Task(chunk.getChunkPos(), future));
|
||||
CompletableFuture<ChunkSizedFullDataView> future = new CompletableFuture<>();
|
||||
this.taskToBuild.addLast(new Task(chunkWrapper.getChunkPos(), future));
|
||||
return future;
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ public class ChunkToLodBuilder
|
||||
{
|
||||
if (LodDataBuilder.canGenerateLodFromChunk(latestChunk))
|
||||
{
|
||||
ChunkSizedFullDataSource data = LodDataBuilder.createChunkData(latestChunk);
|
||||
ChunkSizedFullDataView data = LodDataBuilder.createChunkData(latestChunk);
|
||||
if (data != null)
|
||||
{
|
||||
task.future.complete(data);
|
||||
|
||||
+24
-28
@@ -1,14 +1,14 @@
|
||||
package com.seibel.lod.core.dataObjects.transformers;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IIncompleteFullDataSource;
|
||||
import com.seibel.lod.core.util.RenderDataPointUtil;
|
||||
import com.seibel.lod.core.dataObjects.render.ColumnRenderSource;
|
||||
import com.seibel.lod.core.dataObjects.render.columnViews.ColumnArrayView;
|
||||
import com.seibel.lod.core.dataObjects.render.columnViews.ColumnQuadView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.config.Config;
|
||||
@@ -50,13 +50,13 @@ public class FullToColumnTransformer
|
||||
* @throws InterruptedException Can be caused by interrupting the thread upstream.
|
||||
* Generally thrown if the method is running after the client leaves the current world.
|
||||
*/
|
||||
public static ColumnRenderSource transformFullDataToColumnData(IDhClientLevel level, FullDataSource data) throws InterruptedException
|
||||
public static ColumnRenderSource transformFullDataToColumnData(IDhClientLevel level, CompleteFullDataSource fullDataSource) throws InterruptedException
|
||||
{
|
||||
final DhSectionPos pos = data.getSectionPos();
|
||||
final byte dataDetail = data.getDataDetail();
|
||||
final int vertSize = Config.Client.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(data.getDataDetail());
|
||||
final DhSectionPos pos = fullDataSource.getSectionPos();
|
||||
final byte dataDetail = fullDataSource.getDataDetailLevel();
|
||||
final int vertSize = Config.Client.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(fullDataSource.getDataDetailLevel());
|
||||
final ColumnRenderSource columnSource = new ColumnRenderSource(pos, vertSize, level.getMinY());
|
||||
if (data.isEmpty())
|
||||
if (fullDataSource.isEmpty())
|
||||
{
|
||||
return columnSource;
|
||||
}
|
||||
@@ -75,7 +75,7 @@ public class FullToColumnTransformer
|
||||
throwIfThreadInterrupted();
|
||||
|
||||
ColumnArrayView columnArrayView = columnSource.getVerticalDataPointView(x, z);
|
||||
SingleFullArrayView fullArrayView = data.get(x, z);
|
||||
SingleFullArrayView fullArrayView = fullDataSource.get(x, z);
|
||||
convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView, 1);
|
||||
|
||||
if (fullArrayView.doesItExist())
|
||||
@@ -116,8 +116,8 @@ public class FullToColumnTransformer
|
||||
public static ColumnRenderSource transformIncompleteDataToColumnData(IDhClientLevel level, IIncompleteFullDataSource data) throws InterruptedException
|
||||
{
|
||||
final DhSectionPos pos = data.getSectionPos();
|
||||
final byte dataDetail = data.getDataDetail();
|
||||
final int vertSize = Config.Client.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(data.getDataDetail());
|
||||
final byte dataDetail = data.getDataDetailLevel();
|
||||
final int vertSize = Config.Client.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(data.getDataDetailLevel());
|
||||
final ColumnRenderSource columnSource = new ColumnRenderSource(pos, vertSize, level.getMinY());
|
||||
if (data.isEmpty())
|
||||
{
|
||||
@@ -162,37 +162,33 @@ public class FullToColumnTransformer
|
||||
* @throws InterruptedException Can be caused by interrupting the thread upstream.
|
||||
* Generally thrown if the method is running after the client leaves the current world.
|
||||
*/
|
||||
public static void writeFullDataChunkToColumnData(ColumnRenderSource render, IDhClientLevel level, ChunkSizedFullDataSource data) throws InterruptedException
|
||||
public static void writeFullDataChunkToColumnData(ColumnRenderSource render, IDhClientLevel level, ChunkSizedFullDataView chunkDataView) throws InterruptedException
|
||||
{
|
||||
if (data.dataDetail != 0)
|
||||
{
|
||||
throw new UnsupportedOperationException("To be implemented");
|
||||
}
|
||||
|
||||
final DhSectionPos pos = render.getSectionPos();
|
||||
final int renderOffsetX = (data.x * 16) - pos.getCorner().getCornerBlockPos().x;
|
||||
final int renderOffsetZ = (data.z * 16) - pos.getCorner().getCornerBlockPos().z;
|
||||
final int renderOffsetX = (chunkDataView.pos.x * LodUtil.CHUNK_WIDTH) - pos.getCorner().getCornerBlockPos().x;
|
||||
final int renderOffsetZ = (chunkDataView.pos.z * LodUtil.CHUNK_WIDTH) - pos.getCorner().getCornerBlockPos().z;
|
||||
final int blockX = pos.getCorner().getCornerBlockPos().x;
|
||||
final int blockZ = pos.getCorner().getCornerBlockPos().z;
|
||||
final int perRenderWidth = 1 << render.getDataDetail();
|
||||
final int perDataWidth = 1 << data.dataDetail;
|
||||
final int perDataWidth = 1 << chunkDataView.detailLevel;
|
||||
render.markNotEmpty();
|
||||
if (data.dataDetail == render.getDataDetail())
|
||||
|
||||
if (chunkDataView.detailLevel == render.getDataDetail())
|
||||
{
|
||||
if (renderOffsetX < 0 || renderOffsetX + 16 > render.getDataSize() || renderOffsetZ < 0 || renderOffsetZ + 16 > render.getDataSize())
|
||||
if (renderOffsetX < 0 || renderOffsetX + LodUtil.CHUNK_WIDTH > render.getDataSize() || renderOffsetZ < 0 || renderOffsetZ + LodUtil.CHUNK_WIDTH > render.getDataSize())
|
||||
{
|
||||
throw new IllegalArgumentException("Data offset is out of bounds");
|
||||
}
|
||||
|
||||
|
||||
for (int x = 0; x < 16; x++)
|
||||
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++)
|
||||
{
|
||||
throwIfThreadInterrupted();
|
||||
|
||||
ColumnArrayView columnArrayView = render.getVerticalDataPointView(renderOffsetX + x, renderOffsetZ + z);
|
||||
SingleFullArrayView fullArrayView = data.get(x, z);
|
||||
SingleFullArrayView fullArrayView = chunkDataView.get(x, z);
|
||||
convertColumnData(level, blockX + perRenderWidth * (renderOffsetX + x),
|
||||
blockZ + perRenderWidth * (renderOffsetZ + z),
|
||||
columnArrayView, fullArrayView, 2);
|
||||
@@ -203,12 +199,12 @@ public class FullToColumnTransformer
|
||||
}
|
||||
}
|
||||
}
|
||||
render.fillDebugFlag(renderOffsetX, renderOffsetZ, 16, 16, ColumnRenderSource.DebugSourceFlag.DIRECT);
|
||||
render.fillDebugFlag(renderOffsetX, renderOffsetZ, LodUtil.CHUNK_WIDTH, LodUtil.CHUNK_WIDTH, ColumnRenderSource.DebugSourceFlag.DIRECT);
|
||||
}
|
||||
else
|
||||
{
|
||||
final int dataPerRender = 1 << (render.getDataDetail() - data.dataDetail);
|
||||
final int dataSize = 16 / dataPerRender;
|
||||
final int dataPerRender = 1 << (render.getDataDetail() - chunkDataView.detailLevel);
|
||||
final int dataSize = LodUtil.CHUNK_WIDTH / dataPerRender;
|
||||
final int vertSize = render.getVerticalSize();
|
||||
long[] tempRender = new long[dataPerRender * dataPerRender * vertSize];
|
||||
if (renderOffsetX < 0 || renderOffsetX + dataSize > render.getDataSize() || renderOffsetZ < 0 || renderOffsetZ + dataSize > render.getDataSize())
|
||||
@@ -230,7 +226,7 @@ public class FullToColumnTransformer
|
||||
|
||||
|
||||
ColumnArrayView columnArrayView = tempQuadView.get(ox, oz);
|
||||
SingleFullArrayView fullArrayView = data.get(x * dataPerRender + ox, z * dataPerRender + oz);
|
||||
SingleFullArrayView fullArrayView = chunkDataView.get(x * dataPerRender + ox, z * dataPerRender + oz);
|
||||
convertColumnData(level, blockX + perRenderWidth * (renderOffsetX + x) + perDataWidth * ox,
|
||||
blockZ + perRenderWidth * (renderOffsetZ + z) + perDataWidth * oz,
|
||||
columnArrayView, fullArrayView, 2);
|
||||
|
||||
+15
-15
@@ -1,6 +1,6 @@
|
||||
package com.seibel.lod.core.dataObjects.transformers;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.util.FullDataPointUtil;
|
||||
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
@@ -12,29 +12,29 @@ import it.unimi.dsi.fastutil.longs.LongArrayList;
|
||||
|
||||
public class LodDataBuilder {
|
||||
private static final IBlockStateWrapper AIR = SingletonInjector.INSTANCE.get(IWrapperFactory.class).getAirBlockStateWrapper();
|
||||
public static ChunkSizedFullDataSource createChunkData(IChunkWrapper chunk) {
|
||||
if (!canGenerateLodFromChunk(chunk)) return null;
|
||||
public static ChunkSizedFullDataView createChunkData(IChunkWrapper chunkWrapper) {
|
||||
if (!canGenerateLodFromChunk(chunkWrapper)) return null;
|
||||
|
||||
ChunkSizedFullDataSource chunkData = new ChunkSizedFullDataSource((byte)0, chunk.getChunkPos().x, chunk.getChunkPos().z);
|
||||
ChunkSizedFullDataView chunkData = new ChunkSizedFullDataView(chunkWrapper.getChunkPos());
|
||||
|
||||
for (int x=0; x<16; x++) {
|
||||
for (int z=0; z<16; z++) {
|
||||
LongArrayList longs = new LongArrayList(chunk.getHeight()/4);
|
||||
int lastY = chunk.getMaxBuildHeight();
|
||||
IBiomeWrapper biome = chunk.getBiome(x, lastY, z);
|
||||
LongArrayList longs = new LongArrayList(chunkWrapper.getHeight()/4);
|
||||
int lastY = chunkWrapper.getMaxBuildHeight();
|
||||
IBiomeWrapper biome = chunkWrapper.getBiome(x, lastY, z);
|
||||
IBlockStateWrapper blockState = AIR;
|
||||
int mappedId = chunkData.getMapping().addIfNotPresentAndGetId(biome, blockState);
|
||||
// FIXME: The +1 offset to reproduce the old behavior. Remove this when we get per-face lighting
|
||||
byte light = (byte) ((chunk.getBlockLight(x,lastY+1,z) << 4) + chunk.getSkyLight(x,lastY+1,z));
|
||||
int y=chunk.getMaxY(x, z);
|
||||
byte light = (byte) ((chunkWrapper.getBlockLight(x,lastY+1,z) << 4) + chunkWrapper.getSkyLight(x,lastY+1,z));
|
||||
int y=chunkWrapper.getMaxY(x, z);
|
||||
|
||||
for (; y>=chunk.getMinBuildHeight(); y--) {
|
||||
IBiomeWrapper newBiome = chunk.getBiome(x, y, z);
|
||||
IBlockStateWrapper newBlockState = chunk.getBlockState(x, y, z);
|
||||
byte newLight = (byte) ((chunk.getBlockLight(x,y+1,z) << 4) + chunk.getSkyLight(x,y+1,z));
|
||||
for (; y>=chunkWrapper.getMinBuildHeight(); y--) {
|
||||
IBiomeWrapper newBiome = chunkWrapper.getBiome(x, y, z);
|
||||
IBlockStateWrapper newBlockState = chunkWrapper.getBlockState(x, y, z);
|
||||
byte newLight = (byte) ((chunkWrapper.getBlockLight(x,y+1,z) << 4) + chunkWrapper.getSkyLight(x,y+1,z));
|
||||
|
||||
if (!newBiome.equals(biome) || !newBlockState.equals(blockState)) {
|
||||
longs.add(FullDataPointUtil.encode(mappedId, lastY-y, y+1 - chunk.getMinBuildHeight(), light));
|
||||
longs.add(FullDataPointUtil.encode(mappedId, lastY-y, y+1 - chunkWrapper.getMinBuildHeight(), light));
|
||||
biome = newBiome;
|
||||
blockState = newBlockState;
|
||||
mappedId = chunkData.getMapping().addIfNotPresentAndGetId(biome, blockState);
|
||||
@@ -47,7 +47,7 @@ public class LodDataBuilder {
|
||||
// lastY = y;
|
||||
// }
|
||||
}
|
||||
longs.add(FullDataPointUtil.encode(mappedId, lastY-y, y+1 - chunk.getMinBuildHeight(), light));
|
||||
longs.add(FullDataPointUtil.encode(mappedId, lastY-y, y+1 - chunkWrapper.getMinBuildHeight(), light));
|
||||
|
||||
chunkData.setSingleColumn(longs.toArray(new long[0]), x, z);
|
||||
}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
package com.seibel.lod.core.file.fullDatafile;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IIncompleteFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.SingleChunkFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.SparseFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.*;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource;
|
||||
import com.seibel.lod.core.util.FileUtil;
|
||||
import com.seibel.lod.core.file.metaData.BaseMetaData;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
@@ -37,7 +34,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider
|
||||
final IDhLevel level;
|
||||
final File saveDir;
|
||||
AtomicInteger topDetailLevel = new AtomicInteger(-1);
|
||||
final int minDetailLevel = FullDataSource.SECTION_SIZE_OFFSET;
|
||||
final int minDetailLevel = CompleteFullDataSource.SECTION_SIZE_OFFSET;
|
||||
|
||||
|
||||
|
||||
@@ -185,7 +182,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider
|
||||
|
||||
//TODO: The following check is temporary as we only sample corner points, which means
|
||||
// on a very different level, we may not need the entire section at all.
|
||||
if (!FullDataSource.firstDataPosCanAffectSecond(basePos, subPos))
|
||||
if (!CompleteFullDataSource.firstDataPosCanAffectSecond(basePos, subPos))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -217,7 +214,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider
|
||||
private void recursiveGetDataFilesForPosition(int childIndex, DhSectionPos basePos, DhSectionPos pos, ArrayList<FullDataMetaFile> preexistingFiles, ArrayList<DhSectionPos> missingFilePositions)
|
||||
{
|
||||
DhSectionPos childPos = pos.getChildByIndex(childIndex);
|
||||
if (FullDataSource.firstDataPosCanAffectSecond(basePos, childPos))
|
||||
if (CompleteFullDataSource.firstDataPosCanAffectSecond(basePos, childPos))
|
||||
{
|
||||
FullDataMetaFile metaFile = this.files.get(childPos);
|
||||
if (metaFile != null)
|
||||
@@ -276,15 +273,15 @@ public class FullDataFileHandler implements IFullDataSourceProvider
|
||||
|
||||
/** This call is concurrent. I.e. it supports being called by multiple threads at the same time. */
|
||||
@Override
|
||||
public void write(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData)
|
||||
public void write(DhSectionPos sectionPos, ChunkSizedFullDataView chunkDataView)
|
||||
{
|
||||
DhLodPos chunkPos = new DhLodPos((byte) (chunkData.dataDetail+4), chunkData.x, chunkData.z);
|
||||
DhLodPos chunkPos = chunkDataView.getLodPos();
|
||||
LodUtil.assertTrue(chunkPos.overlapsExactly(sectionPos.getSectionBBoxPos()), "Chunk "+chunkPos+" does not overlap section "+sectionPos);
|
||||
|
||||
chunkPos = chunkPos.convertToDetailLevel((byte) this.minDetailLevel);
|
||||
this.writeChunkDataToMetaFile(new DhSectionPos(chunkPos.detailLevel, chunkPos.x, chunkPos.z), chunkData);
|
||||
this.writeChunkDataToMetaFile(new DhSectionPos(chunkPos.detailLevel, chunkPos.x, chunkPos.z), chunkDataView);
|
||||
}
|
||||
private void writeChunkDataToMetaFile(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData)
|
||||
private void writeChunkDataToMetaFile(DhSectionPos sectionPos, ChunkSizedFullDataView chunkData)
|
||||
{
|
||||
FullDataMetaFile metaFile = this.files.get(sectionPos);
|
||||
if (metaFile != null)
|
||||
@@ -346,7 +343,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider
|
||||
{
|
||||
// None exist.
|
||||
IIncompleteFullDataSource incompleteDataSource = pos.sectionDetailLevel <= SparseFullDataSource.MAX_SECTION_DETAIL ?
|
||||
SparseFullDataSource.createEmpty(pos) : SingleChunkFullDataSource.createEmpty(pos);
|
||||
SparseFullDataSource.createEmpty(pos) : SpottyFullDataSource.createEmpty(pos);
|
||||
return CompletableFuture.completedFuture(incompleteDataSource);
|
||||
}
|
||||
else
|
||||
@@ -362,7 +359,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider
|
||||
final ArrayList<CompletableFuture<Void>> futures = new ArrayList<>(existFiles.size());
|
||||
final IIncompleteFullDataSource dataSource = pos.sectionDetailLevel <= SparseFullDataSource.MAX_SECTION_DETAIL ?
|
||||
SparseFullDataSource.createEmpty(pos) :
|
||||
SingleChunkFullDataSource.createEmpty(pos);
|
||||
SpottyFullDataSource.createEmpty(pos);
|
||||
|
||||
for (FullDataMetaFile metaFile : existFiles)
|
||||
{
|
||||
@@ -383,7 +380,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider
|
||||
);
|
||||
}
|
||||
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
|
||||
.thenApply((v) -> dataSource.trySelfPromote());
|
||||
.thenApply((v) -> dataSource.tryPromotingToCompleteDataSource());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -410,7 +407,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider
|
||||
|
||||
if (source instanceof IIncompleteFullDataSource)
|
||||
{
|
||||
IFullDataSource newSource = ((IIncompleteFullDataSource) source).trySelfPromote();
|
||||
IFullDataSource newSource = ((IIncompleteFullDataSource) source).tryPromotingToCompleteDataSource();
|
||||
changed |= newSource != source;
|
||||
source = newSource;
|
||||
}
|
||||
@@ -437,7 +434,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider
|
||||
|
||||
if (sourceLocal instanceof IIncompleteFullDataSource)
|
||||
{
|
||||
IFullDataSource newSource = ((IIncompleteFullDataSource) sourceLocal).trySelfPromote();
|
||||
IFullDataSource newSource = ((IIncompleteFullDataSource) sourceLocal).tryPromotingToCompleteDataSource();
|
||||
changed |= newSource != sourceLocal;
|
||||
sourceLocal = newSource;
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.loader.AbstractFullDataSourceLoader;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.file.metaData.BaseMetaData;
|
||||
import com.seibel.lod.core.pos.DhLodPos;
|
||||
@@ -47,7 +47,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile
|
||||
//TODO: use ConcurrentAppendSingleSwapContainer<LodDataSource> instead of below:
|
||||
private static class GuardedMultiAppendQueue {
|
||||
ReentrantReadWriteLock appendLock = new ReentrantReadWriteLock();
|
||||
ConcurrentLinkedQueue<ChunkSizedFullDataSource> queue = new ConcurrentLinkedQueue<>();
|
||||
ConcurrentLinkedQueue<ChunkSizedFullDataView> queue = new ConcurrentLinkedQueue<>();
|
||||
}
|
||||
|
||||
// ===Concurrent Write stuff===
|
||||
@@ -146,11 +146,11 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile
|
||||
// }
|
||||
// }
|
||||
|
||||
public void addToWriteQueue(ChunkSizedFullDataSource chunkDataSource)
|
||||
public void addToWriteQueue(ChunkSizedFullDataView chunkDataSource)
|
||||
{
|
||||
debugCheck();
|
||||
DhLodPos chunkPos = new DhLodPos((byte) (chunkDataSource.dataDetail + 4), chunkDataSource.x, chunkDataSource.z);
|
||||
LodUtil.assertTrue(pos.getSectionBBoxPos().overlapsExactly(chunkPos), "Chunk pos "+chunkPos+" doesn't overlap with section "+pos);
|
||||
DhLodPos chunkLodPos = new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkDataSource.pos.x, chunkDataSource.pos.z);
|
||||
LodUtil.assertTrue(pos.getSectionBBoxPos().overlapsExactly(chunkLodPos), "Chunk pos "+chunkLodPos+" doesn't overlap with section "+pos);
|
||||
//LOGGER.info("Write Chunk {} to file {}", chunkPos, pos);
|
||||
|
||||
GuardedMultiAppendQueue writeQueue = this.writeQueue.get();
|
||||
@@ -293,7 +293,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile
|
||||
private static BaseMetaData makeMetaData(IFullDataSource data) {
|
||||
AbstractFullDataSourceLoader loader = AbstractFullDataSourceLoader.getLoader(data.getClass(), data.getDataVersion());
|
||||
return new BaseMetaData(data.getSectionPos(), -1,
|
||||
data.getDataDetail(), data.getWorldGenStep(), (loader == null ? 0 : loader.datatypeId), data.getDataVersion());
|
||||
data.getDataDetailLevel(), data.getWorldGenStep(), (loader == null ? 0 : loader.datatypeId), data.getDataVersion());
|
||||
}
|
||||
|
||||
// "unchecked": Suppress casting of CompletableFuture<?> to CompletableFuture<LodDataSource>
|
||||
@@ -398,7 +398,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile
|
||||
{
|
||||
// Write/Update data
|
||||
LodUtil.assertTrue(metaData != null);
|
||||
metaData.dataLevel = fullDataSource.getDataDetail();
|
||||
metaData.dataLevel = fullDataSource.getDataDetailLevel();
|
||||
fullDataSourceLoader = AbstractFullDataSourceLoader.getLoader(fullDataSource.getClass(), fullDataSource.getDataVersion());
|
||||
LodUtil.assertTrue(fullDataSourceLoader != null, "No loader for "+fullDataSource.getClass()+" (v"+fullDataSource.getDataVersion()+")");
|
||||
dataType = fullDataSource.getClass();
|
||||
@@ -430,7 +430,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile
|
||||
{
|
||||
this.swapWriteQueue();
|
||||
int count = this._backQueue.queue.size();
|
||||
for (ChunkSizedFullDataSource chunk : this._backQueue.queue)
|
||||
for (ChunkSizedFullDataView chunk : this._backQueue.queue)
|
||||
{
|
||||
fullDataSource.update(chunk);
|
||||
}
|
||||
|
||||
+7
-7
@@ -2,9 +2,9 @@ package com.seibel.lod.core.file.fullDatafile;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IIncompleteFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.SparseFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.SingleChunkFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.SpottyFullDataSource;
|
||||
import com.seibel.lod.core.generation.tasks.IWorldGenTaskTracker;
|
||||
import com.seibel.lod.core.generation.WorldGenerationQueue;
|
||||
import com.seibel.lod.core.generation.tasks.WorldGenResult;
|
||||
@@ -92,7 +92,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
|
||||
}
|
||||
else
|
||||
{
|
||||
incompleteFullDataSource = SingleChunkFullDataSource.createEmpty(pos);
|
||||
incompleteFullDataSource = SpottyFullDataSource.createEmpty(pos);
|
||||
}
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
|
||||
{
|
||||
// queue this section to be generated
|
||||
GenTask genTask = new GenTask(pos, new WeakReference<>(incompleteFullDataSource));
|
||||
worldGenQueue.submitGenTask(incompleteFullDataSource.getSectionPos().getSectionBBoxPos(), incompleteFullDataSource.getDataDetail(), genTask)
|
||||
worldGenQueue.submitGenTask(incompleteFullDataSource.getSectionPos().getSectionBBoxPos(), incompleteFullDataSource.getDataDetailLevel(), genTask)
|
||||
.whenComplete((genTaskResult, ex) -> this.onWorldGenTaskComplete(genTaskResult, ex, genTask, pos));
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
|
||||
}
|
||||
|
||||
return CompletableFuture.allOf(loadDataFutures.toArray(new CompletableFuture[0]))
|
||||
.thenApply((voidValue) -> incompleteFullDataSource.trySelfPromote());
|
||||
.thenApply((voidValue) -> incompleteFullDataSource.tryPromotingToCompleteDataSource());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +218,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
|
||||
public boolean isMemoryAddressValid() { return this.targetFullDataSourceRef.get() != null; }
|
||||
|
||||
@Override
|
||||
public Consumer<ChunkSizedFullDataSource> getOnGenTaskCompleteConsumer()
|
||||
public Consumer<ChunkSizedFullDataView> getOnGenTaskCompleteConsumer()
|
||||
{
|
||||
if (this.loadedTargetFullDataSource == null)
|
||||
{
|
||||
@@ -231,7 +231,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
|
||||
|
||||
return (chunkSizedFullDataSource) ->
|
||||
{
|
||||
if (chunkSizedFullDataSource.getBBoxLodPos().overlapsExactly(this.loadedTargetFullDataSource.getSectionPos().getSectionBBoxPos()))
|
||||
if (chunkSizedFullDataSource.getLodPos().overlapsExactly(this.loadedTargetFullDataSource.getSectionPos().getSectionBBoxPos()))
|
||||
{
|
||||
GeneratedFullDataFileHandler.this.write(this.loadedTargetFullDataSource.getSectionPos(), chunkSizedFullDataSource);
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.seibel.lod.core.file.fullDatafile;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.file.metaData.BaseMetaData;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
|
||||
@@ -17,7 +17,7 @@ public interface IFullDataSourceProvider extends AutoCloseable
|
||||
void addScannedFile(Collection<File> detectedFiles);
|
||||
|
||||
CompletableFuture<IFullDataSource> read(DhSectionPos pos);
|
||||
void write(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData);
|
||||
void write(DhSectionPos sectionPos, ChunkSizedFullDataView chunkData);
|
||||
CompletableFuture<Void> flushAndSave();
|
||||
|
||||
//long getCacheVersion(DhSectionPos sectionPos);
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
package com.seibel.lod.core.file.renderfile;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.render.ColumnRenderSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
|
||||
import java.io.File;
|
||||
@@ -18,7 +18,7 @@ public interface ILodRenderSourceProvider extends AutoCloseable
|
||||
{
|
||||
CompletableFuture<ColumnRenderSource> readAsync(DhSectionPos pos);
|
||||
void addScannedFile(Collection<File> detectedFiles);
|
||||
void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData);
|
||||
void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataView chunkData);
|
||||
CompletableFuture<Void> flushAndSaveAsync();
|
||||
|
||||
/** Returns true if the data was refreshed, false otherwise */
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.seibel.lod.core.file.renderfile;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.render.ColumnRenderLoader;
|
||||
import com.seibel.lod.core.dataObjects.render.ColumnRenderSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.file.metaData.BaseMetaData;
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
@@ -77,9 +77,9 @@ public class RenderMetaDataFile extends AbstractMetaDataContainerFile
|
||||
|
||||
// FIXME: This can cause concurrent modification of LodRenderSource.
|
||||
// Not sure if it will cause issues or not.
|
||||
public void updateChunkIfNeeded(ChunkSizedFullDataSource chunkData, IDhClientLevel level)
|
||||
public void updateChunkIfNeeded(ChunkSizedFullDataView chunkDataView, IDhClientLevel level)
|
||||
{
|
||||
DhLodPos chunkPos = new DhLodPos((byte) (chunkData.dataDetail + 4), chunkData.x, chunkData.z);
|
||||
DhLodPos chunkPos = chunkDataView.getLodPos();
|
||||
LodUtil.assertTrue(this.pos.getSectionBBoxPos().overlapsExactly(chunkPos), "Chunk pos {} doesn't overlap with section {}", chunkPos, pos);
|
||||
|
||||
CompletableFuture<ColumnRenderSource> source = this._readCached(this.data.get());
|
||||
@@ -88,7 +88,7 @@ public class RenderMetaDataFile extends AbstractMetaDataContainerFile
|
||||
return;
|
||||
}
|
||||
|
||||
source.thenAccept((renderSource) -> renderSource.fastWrite(chunkData, level));
|
||||
source.thenAccept((renderSource) -> renderSource.fastWrite(chunkDataView, level));
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> flushAndSave(ExecutorService renderCacheThread)
|
||||
|
||||
+11
-11
@@ -3,7 +3,7 @@ package com.seibel.lod.core.file.renderfile;
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.render.ColumnRenderSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.transformers.DataRenderTransformer;
|
||||
import com.seibel.lod.core.file.fullDatafile.IFullDataSourceProvider;
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
@@ -214,14 +214,14 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider
|
||||
* TODO why is there fullData handling in the render file handler?
|
||||
*/
|
||||
@Override
|
||||
public void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData)
|
||||
public void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataView chunkDataView)
|
||||
{
|
||||
this.writeChunkDataToFileRecursively(sectionPos,chunkData);
|
||||
this.fullDataSourceProvider.write(sectionPos, chunkData);
|
||||
this.writeChunkDataToFileRecursively(sectionPos,chunkDataView);
|
||||
this.fullDataSourceProvider.write(sectionPos, chunkDataView);
|
||||
}
|
||||
private void writeChunkDataToFileRecursively(DhSectionPos sectPos, ChunkSizedFullDataSource chunkData)
|
||||
private void writeChunkDataToFileRecursively(DhSectionPos sectPos, ChunkSizedFullDataView chunkDataView)
|
||||
{
|
||||
if (!sectPos.getSectionBBoxPos().overlapsExactly(new DhLodPos((byte) (4 + chunkData.dataDetail), chunkData.x, chunkData.z)))
|
||||
if (!sectPos.getSectionBBoxPos().overlapsExactly(chunkDataView.getLodPos()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -229,17 +229,17 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider
|
||||
|
||||
if (sectPos.sectionDetailLevel > ColumnRenderSource.SECTION_SIZE_OFFSET)
|
||||
{
|
||||
this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(0), chunkData);
|
||||
this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(1), chunkData);
|
||||
this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(2), chunkData);
|
||||
this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(3), chunkData);
|
||||
this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(0), chunkDataView);
|
||||
this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(1), chunkDataView);
|
||||
this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(2), chunkDataView);
|
||||
this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(3), chunkDataView);
|
||||
}
|
||||
|
||||
RenderMetaDataFile metaFile = this.filesBySectionPos.get(sectPos);
|
||||
// Fast path: if there is a file for this section, just write to it.
|
||||
if (metaFile != null)
|
||||
{
|
||||
metaFile.updateChunkIfNeeded(chunkData, this.level);
|
||||
metaFile.updateChunkIfNeeded(chunkDataView, this.level);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -2,7 +2,7 @@ package com.seibel.lod.core.file.subDimMatching;
|
||||
|
||||
import com.seibel.lod.core.config.Config;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.util.FullDataPointUtil;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView;
|
||||
import com.seibel.lod.core.dataObjects.transformers.LodDataBuilder;
|
||||
@@ -165,20 +165,20 @@ public class SubDimensionLevelMatcher implements AutoCloseable
|
||||
LOGGER.info("Player block pos in dimension: [" + playerData.playerBlockPos.getX() + "," + playerData.playerBlockPos.getY() + "," + playerData.playerBlockPos.getZ() + "]");
|
||||
|
||||
// new chunk data
|
||||
ChunkSizedFullDataSource newChunkSizedFullDataSource = LodDataBuilder.createChunkData(newlyLoadedChunk);
|
||||
ChunkSizedFullDataView newChunkSizedFullDataView = LodDataBuilder.createChunkData(newlyLoadedChunk);
|
||||
long[][][] newChunkData = new long[LodUtil.CHUNK_WIDTH][LodUtil.CHUNK_WIDTH][];
|
||||
if (newChunkSizedFullDataSource != null)
|
||||
if (newChunkSizedFullDataView != null)
|
||||
{
|
||||
for (int x = 0; x < LodUtil.CHUNK_WIDTH; x++)
|
||||
{
|
||||
for (int z = 0; z < LodUtil.CHUNK_WIDTH; z++)
|
||||
{
|
||||
long[] array = newChunkSizedFullDataSource.get(x, z).getRaw();
|
||||
long[] array = newChunkSizedFullDataView.get(x, z).getRaw();
|
||||
newChunkData[x][z] = array;
|
||||
}
|
||||
}
|
||||
}
|
||||
boolean newChunkHasData = newChunkSizedFullDataSource != null && newChunkSizedFullDataSource.nonEmptyCount() != 0;
|
||||
boolean newChunkHasData = newChunkSizedFullDataView != null && newChunkSizedFullDataView.nonEmptyCount() != 0;
|
||||
|
||||
// check if the chunk is actually empty
|
||||
if (!newChunkHasData)
|
||||
|
||||
@@ -3,7 +3,7 @@ package com.seibel.lod.core.generation;
|
||||
import com.seibel.lod.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
|
||||
import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator;
|
||||
import com.seibel.lod.core.config.Config;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.transformers.LodDataBuilder;
|
||||
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.generation.tasks.*;
|
||||
@@ -345,7 +345,7 @@ public class WorldGenerationQueue implements Closeable
|
||||
LodUtil.assertTrue(taskDetailLevel >= this.minDataDetail && taskDetailLevel <= this.maxDataDetail);
|
||||
|
||||
DhChunkPos chunkPosMin = new DhChunkPos(taskPos.getCornerBlockPos());
|
||||
LOGGER.info("Generating section "+taskPos+" with granularity "+granularity+" at "+chunkPosMin);
|
||||
//LOGGER.info("Generating section "+taskPos+" with granularity "+granularity+" at "+chunkPosMin);
|
||||
|
||||
this.numberOfTasksQueued++;
|
||||
inProgressTaskGroup.genFuture = startGenerationEvent(this.generator, chunkPosMin, granularity, taskDetailLevel, inProgressTaskGroup.group::onGenerationComplete);
|
||||
@@ -500,7 +500,7 @@ public class WorldGenerationQueue implements Closeable
|
||||
private static CompletableFuture<Void> startGenerationEvent(IDhApiWorldGenerator worldGenerator,
|
||||
DhChunkPos chunkPosMin,
|
||||
byte granularity, byte targetDataDetail,
|
||||
Consumer<ChunkSizedFullDataSource> generationCompleteConsumer)
|
||||
Consumer<ChunkSizedFullDataView> generationCompleteConsumer)
|
||||
{
|
||||
EDhApiDistantGeneratorMode generatorMode = Config.Client.WorldGenerator.distantGeneratorMode.get();
|
||||
return worldGenerator.generateChunks(chunkPosMin.x, chunkPosMin.z, granularity, targetDataDetail, generatorMode, (objectArray) ->
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.seibel.lod.core.generation.tasks;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
@@ -13,6 +13,6 @@ public interface IWorldGenTaskTracker
|
||||
/** Returns true if the task hasn't been garbage collected. */
|
||||
boolean isMemoryAddressValid();
|
||||
|
||||
Consumer<ChunkSizedFullDataSource> getOnGenTaskCompleteConsumer();
|
||||
Consumer<ChunkSizedFullDataView> getOnGenTaskCompleteConsumer();
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.seibel.lod.core.generation.tasks;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.Consumer;
|
||||
@@ -52,6 +52,6 @@ public class SplitWorldGenTaskTracker implements IWorldGenTaskTracker
|
||||
public boolean isMemoryAddressValid() { return this.isValid; }
|
||||
|
||||
@Override
|
||||
public Consumer<ChunkSizedFullDataSource> getOnGenTaskCompleteConsumer() { return this.parentTracker.getOnGenTaskCompleteConsumer(); }
|
||||
public Consumer<ChunkSizedFullDataView> getOnGenTaskCompleteConsumer() { return this.parentTracker.getOnGenTaskCompleteConsumer(); }
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
package com.seibel.lod.core.generation.tasks;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.pos.DhLodPos;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
@@ -29,13 +28,13 @@ public final class WorldGenTaskGroup
|
||||
|
||||
|
||||
|
||||
public void onGenerationComplete(ChunkSizedFullDataSource chunkSizedFullDataSource)
|
||||
public void onGenerationComplete(ChunkSizedFullDataView chunkSizedFullDataView)
|
||||
{
|
||||
Iterator<WorldGenTask> tasks = this.worldGenTasks.iterator();
|
||||
while (tasks.hasNext())
|
||||
{
|
||||
WorldGenTask task = tasks.next();
|
||||
Consumer<ChunkSizedFullDataSource> onGenTaskCompleteConsumer = task.taskTracker.getOnGenTaskCompleteConsumer();
|
||||
Consumer<ChunkSizedFullDataView> onGenTaskCompleteConsumer = task.taskTracker.getOnGenTaskCompleteConsumer();
|
||||
if (onGenTaskCompleteConsumer == null)
|
||||
{
|
||||
tasks.remove();
|
||||
@@ -44,7 +43,7 @@ public final class WorldGenTaskGroup
|
||||
else
|
||||
{
|
||||
// TODO why aren't we removing the task if it has a consumer?
|
||||
onGenTaskCompleteConsumer.accept(chunkSizedFullDataSource);
|
||||
onGenTaskCompleteConsumer.accept(chunkSizedFullDataView);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.seibel.lod.core.level;
|
||||
|
||||
import com.seibel.lod.core.config.Config;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.transformers.ChunkToLodBuilder;
|
||||
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.file.fullDatafile.FullDataFileHandler;
|
||||
@@ -172,16 +172,16 @@ public abstract class AbstractDhClientLevel implements IDhClientLevel
|
||||
@Override
|
||||
public void updateChunkAsync(IChunkWrapper chunk)
|
||||
{
|
||||
CompletableFuture<ChunkSizedFullDataSource> future = this.chunkToLodBuilder.tryGenerateData(chunk);
|
||||
CompletableFuture<ChunkSizedFullDataView> future = this.chunkToLodBuilder.tryGenerateData(chunk);
|
||||
if (future != null)
|
||||
{
|
||||
future.thenAccept(this::saveWrites);
|
||||
}
|
||||
}
|
||||
private void saveWrites(ChunkSizedFullDataSource data)
|
||||
private void saveWrites(ChunkSizedFullDataView data)
|
||||
{
|
||||
ClientRenderState ClientRenderState = this.ClientRenderStateRef.get();
|
||||
DhLodPos pos = data.getBBoxLodPos().convertToDetailLevel(FullDataSource.SECTION_SIZE_OFFSET);
|
||||
DhLodPos pos = data.getLodPos().convertToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET);
|
||||
if (ClientRenderState != null)
|
||||
{
|
||||
ClientRenderState.renderSourceFileHandler.writeChunkDataToFile(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data);
|
||||
|
||||
@@ -1,32 +1,20 @@
|
||||
package com.seibel.lod.core.level;
|
||||
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource;
|
||||
import com.seibel.lod.core.dataObjects.transformers.ChunkToLodBuilder;
|
||||
import com.seibel.lod.core.file.fullDatafile.FullDataFileHandler;
|
||||
import com.seibel.lod.core.file.fullDatafile.IFullDataSourceProvider;
|
||||
import com.seibel.lod.core.file.structure.AbstractSaveStructure;
|
||||
import com.seibel.lod.core.level.states.ClientRenderState;
|
||||
import com.seibel.lod.core.logging.f3.F3Screen;
|
||||
import com.seibel.lod.core.pos.DhLodPos;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.util.FileScanUtil;
|
||||
import com.seibel.lod.core.file.fullDatafile.RemoteFullDataFileHandler;
|
||||
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.pos.DhBlockPos;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
import com.seibel.lod.core.util.math.Mat4f;
|
||||
import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/** The level used when connected to a server */
|
||||
|
||||
Reference in New Issue
Block a user