Optimize some DhSectionPos via mutating the pos and removing duplicate DhLodPos allocations

This commit is contained in:
James Seibel
2023-09-14 22:04:52 -05:00
parent db58aa117a
commit 2cee805645
16 changed files with 116 additions and 73 deletions
@@ -47,15 +47,17 @@ public class FullDataDownSampler
ArrayList<CompletableFuture<IFullDataSource>> futures;
DhLodPos basePos = target.getSectionPos().getSectionBBoxPos().getCornerLodPos(CompleteFullDataSource.SECTION_SIZE_OFFSET);
if (sectionSizeNeeded <= CompleteFullDataSource.SECTION_SIZE_OFFSET)
{
futures = new ArrayList<>(sectionSizeNeeded * sectionSizeNeeded);
for (int ox = 0; ox < sectionSizeNeeded; ox++)
for (int xOffset = 0; xOffset < sectionSizeNeeded; xOffset++)
{
for (int oz = 0; oz < sectionSizeNeeded; oz++)
for (int zOffset = 0; zOffset < sectionSizeNeeded; zOffset++)
{
CompletableFuture<IFullDataSource> future = provider.readAsync(new DhSectionPos(
CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox, basePos.z + oz));
CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + xOffset, basePos.z + zOffset));
future = future.whenComplete((source, ex) -> {
if (ex == null && source != null && source instanceof CompleteFullDataSource)
{
@@ -74,12 +76,12 @@ public class FullDataDownSampler
{
futures = new ArrayList<>(CompleteFullDataSource.WIDTH * CompleteFullDataSource.WIDTH);
int multiplier = sectionSizeNeeded / CompleteFullDataSource.WIDTH;
for (int ox = 0; ox < CompleteFullDataSource.WIDTH; ox++)
for (int xOffset = 0; xOffset < CompleteFullDataSource.WIDTH; xOffset++)
{
for (int oz = 0; oz < CompleteFullDataSource.WIDTH; oz++)
for (int zOffset = 0; zOffset < CompleteFullDataSource.WIDTH; zOffset++)
{
CompletableFuture<IFullDataSource> future = provider.readAsync(new DhSectionPos(
CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox * multiplier, basePos.z + oz * multiplier));
CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + xOffset * multiplier, basePos.z + zOffset * multiplier));
future = future.whenComplete((source, ex) -> {
if (ex == null && source != null && source instanceof CompleteFullDataSource)
{
@@ -99,7 +101,7 @@ public class FullDataDownSampler
public static void downSample(CompleteFullDataSource target, CompleteFullDataSource source)
{
LodUtil.assertTrue(target.getSectionPos().overlaps(source.getSectionPos()));
LodUtil.assertTrue(target.getSectionPos().overlapsExactly(source.getSectionPos()));
LodUtil.assertTrue(target.getDataDetailLevel() > source.getDataDetailLevel());
byte detailDiff = (byte) (target.getDataDetailLevel() - source.getDataDetailLevel());
@@ -20,7 +20,6 @@
package com.seibel.distanthorizons.core.dataObjects.fullData.accessor;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.DhLodPos;
import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.util.FullDataPointUtil;
@@ -34,19 +33,22 @@ import com.seibel.distanthorizons.core.util.LodUtil;
*/
public class ChunkSizedFullDataAccessor extends FullDataArrayAccessor
{
public final DhChunkPos pos;
public final DhChunkPos chunkPos;
public final DhSectionPos sectionPos;
// TODO replace this var with LodUtil.BLOCK_DETAIL_LEVEL
public final byte detailLevel = LodUtil.BLOCK_DETAIL_LEVEL;
public ChunkSizedFullDataAccessor(DhChunkPos pos)
public ChunkSizedFullDataAccessor(DhChunkPos chunkPos)
{
super(new FullDataPointIdMap(new DhSectionPos(pos)),
super(new FullDataPointIdMap(new DhSectionPos(chunkPos)),
new long[LodUtil.CHUNK_WIDTH * LodUtil.CHUNK_WIDTH][0],
LodUtil.CHUNK_WIDTH);
this.pos = pos;
this.chunkPos = chunkPos;
this.sectionPos = new DhSectionPos(LodUtil.CHUNK_DETAIL_LEVEL, this.chunkPos.x, this.chunkPos.z);
}
@@ -68,9 +70,9 @@ public class ChunkSizedFullDataAccessor extends FullDataArrayAccessor
public long emptyCount() { return (LodUtil.CHUNK_WIDTH * LodUtil.CHUNK_WIDTH) - this.nonEmptyCount(); }
public DhLodPos getLodPos() { return new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, this.pos.x, this.pos.z); }
public DhSectionPos getSectionPos() { return this.sectionPos; }
@Override
public String toString() { return this.pos + " " + this.nonEmptyCount(); }
public String toString() { return this.chunkPos + " " + this.nonEmptyCount(); }
}
@@ -277,10 +277,10 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu
@Override
public void update(ChunkSizedFullDataAccessor chunkDataView)
{
LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(chunkDataView.getLodPos()));
LodUtil.assertTrue(this.sectionPos.overlapsExactly(chunkDataView.getSectionPos()));
if (this.getDataDetailLevel() == LodUtil.BLOCK_DETAIL_LEVEL)
{
DhBlockPos2D chunkBlockPos = new DhBlockPos2D(chunkDataView.pos.x * LodUtil.CHUNK_WIDTH, chunkDataView.pos.z * LodUtil.CHUNK_WIDTH);
DhBlockPos2D chunkBlockPos = new DhBlockPos2D(chunkDataView.chunkPos.x * LodUtil.CHUNK_WIDTH, chunkDataView.chunkPos.z * LodUtil.CHUNK_WIDTH);
DhBlockPos2D blockOffset = chunkBlockPos.subtract(this.sectionPos.getMinCornerLodPos().getCornerBlockPos());
LodUtil.assertTrue(blockOffset.x >= 0 && blockOffset.x < WIDTH && blockOffset.z >= 0 && blockOffset.z < WIDTH);
this.isEmpty = false;
@@ -303,7 +303,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu
{
int dataPerFull = 1 << this.getDataDetailLevel();
int fullSize = LodUtil.CHUNK_WIDTH / dataPerFull;
DhLodPos dataOffset = chunkDataView.getLodPos().getCornerLodPos(this.getDataDetailLevel());
DhLodPos dataOffset = chunkDataView.getSectionPos().getMinCornerLodPos(this.getDataDetailLevel());
DhLodPos baseOffset = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel());
int offsetX = dataOffset.x - baseOffset.x;
@@ -324,16 +324,16 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu
{
//FIXME: TEMPORARY
int chunkPerFull = 1 << (this.getDataDetailLevel() - LodUtil.CHUNK_DETAIL_LEVEL);
if (chunkDataView.pos.x % chunkPerFull != 0 || chunkDataView.pos.z % chunkPerFull != 0)
if (chunkDataView.chunkPos.x % chunkPerFull != 0 || chunkDataView.chunkPos.z % chunkPerFull != 0)
{
return;
}
DhLodPos baseOffset = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel());
DhLodPos dataOffset = chunkDataView.getLodPos().convertToDetailLevel(this.getDataDetailLevel());
DhSectionPos dataOffset = chunkDataView.getSectionPos().convertNewToDetailLevel(this.getDataDetailLevel());
int offsetX = dataOffset.x - baseOffset.x;
int offsetZ = dataOffset.z - baseOffset.z;
int offsetX = dataOffset.sectionX - baseOffset.x;
int offsetZ = dataOffset.sectionZ - baseOffset.z;
LodUtil.assertTrue(offsetX >= 0 && offsetX < WIDTH && offsetZ >= 0 && offsetZ < WIDTH);
this.isEmpty = false;
@@ -356,7 +356,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu
/** Returns whether data at the given posToWrite can effect the target region file at posToTest. */
public static boolean firstDataPosCanAffectSecond(DhSectionPos posToWrite, DhSectionPos posToTest)
{
if (!posToWrite.overlaps(posToTest))
if (!posToWrite.overlapsExactly(posToTest))
{
// the testPosition is outside the writePosition
return false;
@@ -418,7 +418,7 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu
public void updateFromLowerCompleteSource(CompleteFullDataSource subData)
{
LodUtil.assertTrue(this.sectionPos.overlaps(subData.sectionPos));
LodUtil.assertTrue(this.sectionPos.overlapsExactly(subData.sectionPos));
LodUtil.assertTrue(subData.sectionPos.sectionDetailLevel < this.sectionPos.sectionDetailLevel);
if (!firstDataPosCanAffectSecond(this.sectionPos, subData.sectionPos))
{
@@ -456,7 +456,7 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo
@Override
public void update(ChunkSizedFullDataAccessor chunkDataView)
{
int arrayOffset = this.calculateOffset(chunkDataView.pos.x, chunkDataView.pos.z);
int arrayOffset = this.calculateOffset(chunkDataView.chunkPos.x, chunkDataView.chunkPos.z);
FullDataArrayAccessor newArray = new FullDataArrayAccessor(this.mapping, new long[this.dataPointsPerSection * this.dataPointsPerSection][], this.dataPointsPerSection);
if (this.getDataDetailLevel() == chunkDataView.detailLevel)
{
@@ -489,7 +489,7 @@ public class HighDetailIncompleteFullDataSource implements IIncompleteFullDataSo
{
DhSectionPos pos = fullDataSource.getSectionPos();
LodUtil.assertTrue(pos.sectionDetailLevel < this.sectionPos.sectionDetailLevel);
LodUtil.assertTrue(pos.overlaps(this.sectionPos));
LodUtil.assertTrue(pos.overlapsExactly(this.sectionPos));
if (fullDataSource.isEmpty())
{
return;
@@ -318,21 +318,21 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp
@Override
public void update(ChunkSizedFullDataAccessor data)
{
LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(data.getLodPos()));
LodUtil.assertTrue(this.sectionPos.overlapsExactly(data.getSectionPos()));
if (this.getDataDetailLevel() >= 4)
{
//FIXME: TEMPORARY
int chunkPerFull = 1 << (this.getDataDetailLevel() - 4);
if (data.pos.x % chunkPerFull != 0 || data.pos.z % chunkPerFull != 0)
if (data.chunkPos.x % chunkPerFull != 0 || data.chunkPos.z % chunkPerFull != 0)
{
return;
}
DhLodPos baseOffset = this.sectionPos.getMinCornerLodPos(this.getDataDetailLevel());
DhLodPos dataOffset = data.getLodPos().convertToDetailLevel(this.getDataDetailLevel());
int offsetX = dataOffset.x - baseOffset.x;
int offsetZ = dataOffset.z - baseOffset.z;
DhSectionPos dataOffset = data.getSectionPos().convertNewToDetailLevel(this.getDataDetailLevel());
int offsetX = dataOffset.sectionX - baseOffset.x;
int offsetZ = dataOffset.sectionZ - baseOffset.z;
LodUtil.assertTrue(offsetX >= 0 && offsetX < WIDTH && offsetZ >= 0 && offsetZ < WIDTH);
this.isEmpty = false;
@@ -354,7 +354,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp
{
DhSectionPos pos = fullDataSource.getSectionPos();
LodUtil.assertTrue(pos.sectionDetailLevel < this.sectionPos.sectionDetailLevel);
LodUtil.assertTrue(pos.overlaps(this.sectionPos));
LodUtil.assertTrue(pos.overlapsExactly(this.sectionPos));
if (fullDataSource.isEmpty())
{
@@ -572,7 +572,7 @@ public class LowDetailIncompleteFullDataSource extends FullDataArrayAccessor imp
public static boolean neededForPosition(DhSectionPos posToWrite, DhSectionPos posToTest)
{
if (!posToWrite.overlaps(posToTest))
if (!posToWrite.overlapsExactly(posToTest))
return false;
if (posToTest.sectionDetailLevel > posToWrite.sectionDetailLevel)
return false;
@@ -308,7 +308,7 @@ public class ColumnRenderSource
*/
public boolean updateWithChunkData(ChunkSizedFullDataAccessor chunkDataView, IDhClientLevel level)
{
final String errorMessagePrefix = "Unable to complete fastWrite for RenderSource pos: [" + this.sectionPos + "] and chunk pos: [" + chunkDataView.pos + "]. Error:";
final String errorMessagePrefix = "Unable to complete fastWrite for RenderSource pos: [" + this.sectionPos + "] and chunk pos: [" + chunkDataView.chunkPos + "]. Error:";
final DhSectionPos renderSourcePos = this.getSectionPos();
@@ -316,8 +316,8 @@ public class ColumnRenderSource
final int sourceBlockZ = renderSourcePos.getMinCornerLodPos().getCornerBlockPos().z;
// offset between the incoming chunk data and this render source
final int blockOffsetX = (chunkDataView.pos.x * LodUtil.CHUNK_WIDTH) - sourceBlockX;
final int blockOffsetZ = (chunkDataView.pos.z * LodUtil.CHUNK_WIDTH) - sourceBlockZ;
final int blockOffsetX = (chunkDataView.chunkPos.x * LodUtil.CHUNK_WIDTH) - sourceBlockX;
final int blockOffsetZ = (chunkDataView.chunkPos.z * LodUtil.CHUNK_WIDTH) - sourceBlockZ;
final int sourceDataPointBlockWidth = BitShiftUtil.powerOfTwo(this.getDataDetail());
@@ -360,27 +360,27 @@ public class ColumnRenderSource
}
this.fillDebugFlag(blockOffsetX, blockOffsetZ, LodUtil.CHUNK_WIDTH, LodUtil.CHUNK_WIDTH, ColumnRenderSource.DebugSourceFlag.DIRECT);
}
else if (chunkDataView.detailLevel < this.getDataDetail() && this.getDataDetail() <= chunkDataView.getLodPos().detailLevel)
else if (chunkDataView.detailLevel < this.getDataDetail() && this.getDataDetail() <= chunkDataView.getSectionPos().sectionDetailLevel)
{
this.markNotEmpty();
// multiple chunk data points converting to 1 column data point
DhLodPos dataCornerPos = chunkDataView.getLodPos().getCornerLodPos(chunkDataView.detailLevel);
DhLodPos dataCornerPos = chunkDataView.getSectionPos().getMinCornerLodPos(chunkDataView.detailLevel);
DhLodPos sourceCornerPos = renderSourcePos.getMinCornerLodPos(this.getDataDetail());
DhLodPos sourceStartingChangePos = dataCornerPos.convertToDetailLevel(this.getDataDetail());
int relStartX = Math.floorMod(sourceStartingChangePos.x, this.getWidthInDataPoints());
int relStartZ = Math.floorMod(sourceStartingChangePos.z, this.getWidthInDataPoints());
int dataToSourceScale = sourceCornerPos.getWidthAtDetail(chunkDataView.detailLevel);
int columnsInChunk = chunkDataView.getLodPos().getWidthAtDetail(this.getDataDetail());
int columnsInChunk = chunkDataView.getSectionPos().getWidthCountForLowerDetailedSection(this.getDataDetail());
for (int ox = 0; ox < columnsInChunk; ox++)
for (int xOffset = 0; xOffset < columnsInChunk; xOffset++)
{
for (int oz = 0; oz < columnsInChunk; oz++)
for (int zOffset = 0; zOffset < columnsInChunk; zOffset++)
{
int relSourceX = relStartX + ox;
int relSourceZ = relStartZ + oz;
int relSourceX = relStartX + xOffset;
int relSourceZ = relStartZ + zOffset;
ColumnArrayView columnArrayView = this.getVerticalDataPointView(relSourceX, relSourceZ);
int hash = columnArrayView.getDataHash();
SingleColumnFullDataAccessor fullArrayView = chunkDataView.get(ox * dataToSourceScale, oz * dataToSourceScale);
SingleColumnFullDataAccessor fullArrayView = chunkDataView.get(xOffset * dataToSourceScale, zOffset * dataToSourceScale);
FullDataToRenderDataTransformer.convertColumnData(level,
sourceBlockX + sourceDataPointBlockWidth * relSourceX,
sourceBlockZ + sourceDataPointBlockWidth * relSourceZ,
@@ -390,14 +390,14 @@ public class ColumnRenderSource
}
this.fillDebugFlag(relStartX, relStartZ, columnsInChunk, columnsInChunk, ColumnRenderSource.DebugSourceFlag.DIRECT);
}
else if (chunkDataView.getLodPos().detailLevel < this.getDataDetail())
else if (chunkDataView.getSectionPos().sectionDetailLevel < this.getDataDetail())
{
// The entire chunk is being converted to a single column data point, possibly.
DhLodPos dataCornerPos = chunkDataView.getLodPos().getCornerLodPos(chunkDataView.detailLevel);
DhLodPos dataCornerPos = chunkDataView.getSectionPos().getMinCornerLodPos(chunkDataView.detailLevel);
DhLodPos sourceCornerPos = renderSourcePos.getMinCornerLodPos(this.getDataDetail());
DhLodPos sourceStartingChangePos = dataCornerPos.convertToDetailLevel(this.getDataDetail());
int chunksPerColumn = sourceStartingChangePos.getWidthAtDetail(chunkDataView.getLodPos().detailLevel);
if (chunkDataView.getLodPos().x % chunksPerColumn != 0 || chunkDataView.getLodPos().z % chunksPerColumn != 0)
int chunksPerColumn = sourceStartingChangePos.getWidthAtDetail(chunkDataView.getSectionPos().sectionDetailLevel);
if (chunkDataView.getSectionPos().sectionX % chunksPerColumn != 0 || chunkDataView.getSectionPos().sectionZ % chunksPerColumn != 0)
{
return false; // not a multiple of the column size, so no change
}
@@ -228,6 +228,8 @@ public class FullDataFileHandler implements IFullDataSourceProvider
byte sectionDetail = posAreaToGet.sectionDetailLevel;
boolean allEmpty = true;
final DhSectionPos subPos = new DhSectionPos((byte)0, 0, 0);
// get all existing files for this position
outerLoop:
while (--sectionDetail >= this.minDetailLevel)
@@ -239,8 +241,8 @@ public class FullDataFileHandler implements IFullDataSourceProvider
{
for (int zOffset = 0; zOffset < count; zOffset++)
{
DhSectionPos subPos = new DhSectionPos(sectionDetail, xOffset + minPos.x, zOffset + minPos.z);
LodUtil.assertTrue(posAreaToGet.overlaps(effectivePos) && subPos.overlaps(posAreaToGet));
subPos.mutate(sectionDetail, xOffset + minPos.x, zOffset + minPos.z);
LodUtil.assertTrue(posAreaToGet.overlapsExactly(effectivePos) && subPos.overlapsExactly(posAreaToGet));
//TODO: The following check is temporary as we only sample corner points, which means
// on a very different level, we may not need the entire section at all.
@@ -317,11 +319,11 @@ public class FullDataFileHandler implements IFullDataSourceProvider
@Override
public void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataAccessor chunkDataView)
{
DhLodPos chunkPos = chunkDataView.getLodPos();
LodUtil.assertTrue(chunkPos.overlapsExactly(sectionPos.getSectionBBoxPos()), "Chunk " + chunkPos + " does not overlap section " + sectionPos);
DhSectionPos chunkSectionPos = chunkDataView.getSectionPos();
LodUtil.assertTrue(chunkSectionPos.overlapsExactly(sectionPos), "Chunk " + chunkSectionPos + " does not overlap section " + sectionPos);
chunkPos = chunkPos.convertToDetailLevel((byte) this.minDetailLevel);
this.writeChunkDataToMetaFile(new DhSectionPos(chunkPos.detailLevel, chunkPos.x, chunkPos.z), chunkDataView);
chunkSectionPos = chunkSectionPos.convertNewToDetailLevel((byte) this.minDetailLevel);
this.writeChunkDataToMetaFile(chunkSectionPos, chunkDataView);
}
private void writeChunkDataToMetaFile(DhSectionPos sectionPos, ChunkSizedFullDataAccessor chunkData)
{
@@ -344,7 +344,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile implements I
{
checkAndLogPhantomDataSourceLifeCycles();
DhLodPos chunkLodPos = new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkAccessor.pos.x, chunkAccessor.pos.z);
DhLodPos chunkLodPos = new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkAccessor.chunkPos.x, chunkAccessor.chunkPos.z);
LodUtil.assertTrue(this.pos.getSectionBBoxPos().overlapsExactly(chunkLodPos), "Chunk pos " + chunkLodPos + " doesn't exactly overlap with section " + this.pos);
//LOGGER.info("Write Chunk {} to file {}", chunkPos, pos);
@@ -349,7 +349,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
return (chunkSizedFullDataSource) ->
{
if (chunkSizedFullDataSource.getLodPos().overlapsExactly(this.loadedTargetFullDataSource.getSectionPos().getSectionBBoxPos()))
if (chunkSizedFullDataSource.getSectionPos().overlapsExactly(this.loadedTargetFullDataSource.getSectionPos()))
{
((DhLevel) level).saveWrites(chunkSizedFullDataSource);
//GeneratedFullDataFileHandler.this.write(this.loadedTargetFullDataSource.getSectionPos(), chunkSizedFullDataSource);
@@ -30,7 +30,6 @@ import com.seibel.distanthorizons.core.file.metaData.AbstractMetaDataContainerFi
import com.seibel.distanthorizons.core.file.metaData.BaseMetaData;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
import com.seibel.distanthorizons.core.pos.DhLodPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderLoader;
import com.seibel.distanthorizons.core.dataObjects.render.ColumnRenderSource;
@@ -136,8 +135,8 @@ public class RenderDataMetaFile extends AbstractMetaDataContainerFile implements
public void updateChunkIfSourceExistsAsync(ChunkSizedFullDataAccessor chunkDataView)
{
DhLodPos chunkPos = chunkDataView.getLodPos();
LodUtil.assertTrue(this.pos.getSectionBBoxPos().overlapsExactly(chunkPos), "Chunk pos " + chunkPos + " doesn't overlap with section " + this.pos);
DhSectionPos chunkSectionPos = chunkDataView.getSectionPos();
LodUtil.assertTrue(this.pos.overlapsExactly(chunkSectionPos), "Chunk pos " + chunkSectionPos + " doesn't overlap with section " + this.pos);
// update the render source if one exists
CompletableFuture<ColumnRenderSource> renderSourceLoadFuture = this.getCachedDataSourceAsync(false);
@@ -156,7 +155,7 @@ public class RenderDataMetaFile extends AbstractMetaDataContainerFile implements
Color debugColor = dataUpdated ? Color.blue : Color.red;
DebugRenderer.makeParticle(
new DebugRenderer.BoxParticle(
new DebugRenderer.Box(chunkDataView.getLodPos(), 32f, 64f + offset, 0.07f, debugColor),
new DebugRenderer.Box(chunkDataView.getSectionPos(), 32f, 64f + offset, 0.07f, debugColor),
2.0, 16f
)
);
@@ -253,16 +253,18 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider
}
private void writeChunkDataToFileRecursively(ChunkSizedFullDataAccessor chunk, byte sectionDetailLevel)
{
DhLodPos boundingPos = chunk.getLodPos();
DhLodPos minSectionPos = boundingPos.convertToDetailLevel(sectionDetailLevel);
DhSectionPos boundingPos = chunk.getSectionPos();
DhSectionPos minSectionPos = boundingPos.convertNewToDetailLevel(sectionDetailLevel);
int width = (sectionDetailLevel > boundingPos.detailLevel) ? 1 : boundingPos.getWidthAtDetail(sectionDetailLevel);
DhSectionPos fileSectionPos = new DhSectionPos((byte)0, 0, 0);
int width = (sectionDetailLevel > boundingPos.sectionDetailLevel) ? 1 : boundingPos.getWidthCountForLowerDetailedSection(sectionDetailLevel);
for (int xOffset = 0; xOffset < width; xOffset++)
{
for (int zOffset = 0; zOffset < width; zOffset++)
{
DhSectionPos sectionPos = new DhSectionPos(sectionDetailLevel, minSectionPos.x + xOffset, minSectionPos.z + zOffset);
RenderDataMetaFile metaFile = this.metaFileBySectionPos.get(sectionPos); // bypass the getLoadOrMakeFile() since we only want cached files.
fileSectionPos.mutate(sectionDetailLevel, minSectionPos.sectionX + xOffset, minSectionPos.sectionZ + zOffset);
RenderDataMetaFile metaFile = this.metaFileBySectionPos.get(fileSectionPos); // bypass the getLoadOrMakeFile() since we only want cached files.
if (metaFile != null)
{
metaFile.updateChunkIfSourceExistsAsync(chunk);
@@ -175,16 +175,16 @@ public class ClientLevelModule implements Closeable
//===============//
public void writeChunkDataToFile(ChunkSizedFullDataAccessor data)
{
DhLodPos pos = data.getLodPos().convertToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET);
DhSectionPos pos = data.getSectionPos().convertNewToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET);
ClientRenderState ClientRenderState = this.ClientRenderStateRef.get();
if (ClientRenderState != null)
{
ClientRenderState.renderSourceFileHandler.writeChunkDataToFile(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data);
ClientRenderState.renderSourceFileHandler.writeChunkDataToFile(pos, data);
}
else
{
this.parentClientLevel.getFileHandler().writeChunkDataToFile(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data);
this.parentClientLevel.getFileHandler().writeChunkDataToFile(pos, data);
}
}
@@ -58,8 +58,9 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel
@Override
public void saveWrites(ChunkSizedFullDataAccessor data)
{
DhLodPos pos = data.getLodPos().convertToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET);
getFileHandler().writeChunkDataToFile(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data);
DhSectionPos pos = data.getSectionPos();
pos.convertSelfToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET);
this.getFileHandler().writeChunkDataToFile(pos, data);
}
@Override
@@ -192,11 +192,14 @@ public class DhLodPos implements Comparable<DhLodPos>
public boolean overlapsExactly(DhLodPos other)
{
if (this.equals(other))
{
return true;
if (this.detailLevel == other.detailLevel)
}
else if (this.detailLevel == other.detailLevel)
{
return false;
if (this.detailLevel > other.detailLevel)
}
else if (this.detailLevel > other.detailLevel)
{
return this.equals(other.convertToDetailLevel(this.detailLevel));
}
@@ -106,6 +106,18 @@ public class DhSectionPos
// converters //
//============//
/**
* Overwrites this section pos with the given input. <br>
* Can be useful to prevent duplicate allocations in high traffic loops but should
* be used sparingly as it could accidentally cause bugs due to unexpected modifications.
*/
public void mutate(byte sectionDetailLevel, int sectionX, int sectionZ)
{
this.sectionDetailLevel = sectionDetailLevel;
this.sectionX = sectionX;
this.sectionZ = sectionZ;
}
/** uses the absolute detail level aka detail levels like {@link LodUtil#CHUNK_DETAIL_LEVEL} instead of the dhSectionPos detailLevels. */
public void convertSelfToDetailLevel(byte newDetailLevel)
{
@@ -256,7 +268,26 @@ public class DhSectionPos
// comparisons //
//=============//
public boolean overlaps(DhSectionPos other) { return this.getSectionBBoxPos().overlapsExactly(other.getSectionBBoxPos()); }
public boolean overlapsExactly(DhSectionPos other)
{
// original logic from DhLodPos
if (this.equals(other))
{
return true;
}
else if (this.sectionDetailLevel == other.sectionDetailLevel)
{
return false;
}
else if (this.sectionDetailLevel > other.sectionDetailLevel)
{
return this.equals(other.convertNewToDetailLevel(this.sectionDetailLevel));
}
else
{
return other.equals(this.convertNewToDetailLevel(other.sectionDetailLevel));
}
}
public boolean contains(DhSectionPos otherPos)
{
@@ -404,6 +404,7 @@ public class QuadTree<T>
{
if (node != null || includeNullNodes)
{
// TODO can these DhSectionPos be pooled?
DhSectionPos rootPos = new DhSectionPos(QuadTree.this.treeMinDetailLevel, pos2D.x, pos2D.y);
if (QuadTree.this.isSectionPosInBounds(rootPos))
{