Replace LevelPosUtil.convert() with DhLodPos.convertToDetailLevel()

This commit is contained in:
James Seibel
2023-01-02 11:13:31 -06:00
parent 7311664acd
commit 9e3f729c8f
13 changed files with 44 additions and 71 deletions
@@ -24,15 +24,16 @@ import com.seibel.lod.core.datatype.column.accessor.ColumnFormat;
import com.seibel.lod.api.enums.rendering.EDebugMode;
import com.seibel.lod.core.dependencyInjection.SingletonInjector;
import com.seibel.lod.core.datatype.column.accessor.ColumnArrayView;
import com.seibel.lod.core.pos.DhLodPos;
import com.seibel.lod.core.util.BitShiftUtil;
import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.util.LevelPosUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
/**
* Builds LODs as rectangular prisms.
* @author James Seibel
* @version 3-19-2022
* @version 2022-1-2
*/
public class CubicLodTemplate
{
@@ -42,14 +43,19 @@ public class CubicLodTemplate
public static void addLodToBuffer(long data, long topData, long botData, ColumnArrayView[][] adjData,
byte detailLevel, int offsetPosX, int offsetOosZ, LodQuadBuilder quadBuilder, EDebugMode debugging, ColumnRenderSource.DebugSourceFlag debugSource)
{
short width = (short) (1 << detailLevel);
short x = (short) LevelPosUtil.convert(detailLevel, offsetPosX, LodUtil.BLOCK_DETAIL_LEVEL);
DhLodPos blockOffsetPos = new DhLodPos(detailLevel, offsetPosX, offsetOosZ).convertToDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL);
short width = (short) BitShiftUtil.powerOfTwo(detailLevel);
short x = (short) blockOffsetPos.x;
short y = ColumnFormat.getDepth(data);
short z = (short) LevelPosUtil.convert(detailLevel, offsetOosZ, LodUtil.BLOCK_DETAIL_LEVEL);
short z = (short) (short) blockOffsetPos.z;
short dy = (short) (ColumnFormat.getHeight(data) - y);
if (dy == 0)
{
return;
if (dy < 0)
}
else if (dy < 0)
{
throw new IllegalArgumentException("Negative y size for the data! Data: " + ColumnFormat.toString(data));
}
@@ -77,7 +77,7 @@ public class FullDataDownSampler {
return;
}
DhLodPos trgOffset = trgPos.getCorner(target.getDataDetail());
DhLodPos srcOffset = srcPos.getSectionBBoxPos().convertUpwardsTo(target.getDataDetail());
DhLodPos srcOffset = srcPos.getSectionBBoxPos().convertToDetailLevel(target.getDataDetail());
int offsetX = trgOffset.x - srcOffset.x;
int offsetZ = trgOffset.z - srcOffset.z;
LodUtil.assertTrue(offsetX >= 0 && offsetX < FullDataSource.SECTION_SIZE
@@ -106,7 +106,7 @@ public class FullDataSource extends FullArrayView implements ILodDataSource
if (data.x % chunkPerFull != 0 || data.z % chunkPerFull != 0)
return;
DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail());
DhLodPos dataOffset = data.getBBoxLodPos().convertUpwardsTo(this.getDataDetail());
DhLodPos dataOffset = data.getBBoxLodPos().convertToDetailLevel(this.getDataDetail());
int offsetX = dataOffset.x - baseOffset.x;
int offsetZ = dataOffset.z - baseOffset.z;
LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE);
@@ -273,7 +273,7 @@ public class FullDataSource extends FullArrayView implements ILodDataSource
else
{
// Count == 1
DhLodPos subDataPos = lowerSectPos.getSectionBBoxPos().convertUpwardsTo(targetDataDetail);
DhLodPos subDataPos = lowerSectPos.getSectionBBoxPos().convertToDetailLevel(targetDataDetail);
int dataOffsetX = subDataPos.x - minDataPos.x;
int dataOffsetZ = subDataPos.z - minDataPos.z;
LodUtil.assertTrue(dataOffsetX >= 0 && dataOffsetX < SECTION_SIZE && dataOffsetZ >= 0 && dataOffsetZ < SECTION_SIZE);
@@ -58,7 +58,7 @@ public class SpottyDataSource extends FullArrayView implements IIncompleteDataSo
if (data.x % chunkPerFull != 0 || data.z % chunkPerFull != 0)
return;
DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail());
DhLodPos dataOffset = data.getBBoxLodPos().convertUpwardsTo(this.getDataDetail());
DhLodPos dataOffset = data.getBBoxLodPos().convertToDetailLevel(this.getDataDetail());
int offsetX = dataOffset.x - baseOffset.x;
int offsetZ = dataOffset.z - baseOffset.z;
LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE);
@@ -269,7 +269,7 @@ public class SpottyDataSource extends FullArrayView implements IIncompleteDataSo
if (dataPos.x % lowerSectionsPerData != 0 || dataPos.z % lowerSectionsPerData != 0) return;
DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail());
dataPos = dataPos.convertUpwardsTo(this.getDataDetail());
dataPos = dataPos.convertToDetailLevel(this.getDataDetail());
int offsetX = dataPos.x - basePos.x;
int offsetZ = dataPos.z - basePos.z;
SingleFullArrayView column = sparseSource.tryGet(0, 0);
@@ -307,7 +307,7 @@ public class SpottyDataSource extends FullArrayView implements IIncompleteDataSo
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.convertUpwardsTo(this.getDataDetail());
dataPos = dataPos.convertToDetailLevel(this.getDataDetail());
int offsetX = dataPos.x - basePos.x;
int offsetZ = dataPos.z - basePos.z;
this.isColumnNotEmpty.set(offsetX * SECTION_SIZE + offsetZ, true);
@@ -236,7 +236,7 @@ public class DataFileHandler implements IDataSourceProvider {
{
DhLodPos chunkPos = new DhLodPos((byte) (chunkData.dataDetail+4), chunkData.x, chunkData.z);
LodUtil.assertTrue(chunkPos.overlaps(sectionPos.getSectionBBoxPos()), "Chunk {} does not overlap section {}", chunkPos, sectionPos);
chunkPos = chunkPos.convertUpwardsTo((byte) this.minDetailLevel); // TODO: Handle if chunkData has higher detail than lowestDetail.
chunkPos = chunkPos.convertToDetailLevel((byte) this.minDetailLevel);
this.recursiveWrite(new DhSectionPos(chunkPos.detailLevel, chunkPos.x, chunkPos.z), chunkData);
}
private void recursiveWrite(DhSectionPos sectionPos, ChunkSizedData chunkData)
@@ -191,7 +191,7 @@ public class RenderFileHandler implements IRenderSourceProvider
public void write(DhSectionPos sectionPos, ChunkSizedData chunkData)
{
// can be used for debugging
if (chunkData.getBBoxLodPos().convertUpwardsTo((byte)6).equals(new DhLodPos((byte)6, 10, -11)))
if (chunkData.getBBoxLodPos().convertToDetailLevel((byte)6).equals(new DhLodPos((byte)6, 10, -11)))
{
int doNothing = 0;
}
@@ -149,7 +149,7 @@ public class WorldGenerationQueue implements Closeable
{
// Too small of a chunk. We'll just over-size the generation.
byte parentDetail = (byte) (this.minGranularity + requiredDataDetail);
DhLodPos parentPos = pos.convertUpwardsTo(parentDetail);
DhLodPos parentPos = pos.convertToDetailLevel(parentDetail);
CompletableFuture<Boolean> future = new CompletableFuture<>();
this.looseTasks.add(new WorldGenTask(parentPos, requiredDataDetail, tracker, future));
if (this.closer != null)
@@ -199,7 +199,7 @@ public class WorldGenerationQueue implements Closeable
{ // Obviously, only do so if we aren't at the maxGranularity already
// Check for merging and upping the granularity
DhLodPos corePos = target.pos;
DhLodPos parentPos = corePos.convertUpwardsTo((byte) (corePos.detailLevel + 1));
DhLodPos parentPos = corePos.convertToDetailLevel((byte) (corePos.detailLevel + 1));
int targetChildId = target.pos.getChildIndexOfParent();
boolean allPassed = true;
for (int i = 0; i < 4; i++)
@@ -302,7 +302,7 @@ public class WorldGenerationQueue implements Closeable
boolean didAnything = false;
while (++granularity <= this.maxGranularity)
{
group = this.taskGroups.get(task.pos.convertUpwardsTo((byte) (taskDataDetail + granularity)));
group = this.taskGroups.get(task.pos.convertToDetailLevel((byte) (taskDataDetail + granularity)));
if (group != null && group.dataDetail == taskDataDetail)
{
// We can just append to the higher granularity group one
@@ -118,7 +118,7 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel
private void saveWrites(ChunkSizedData data)
{
RenderState rs = this.renderState.get();
DhLodPos pos = data.getBBoxLodPos().convertUpwardsTo(FullDataSource.SECTION_SIZE_OFFSET);
DhLodPos pos = data.getBBoxLodPos().convertToDetailLevel(FullDataSource.SECTION_SIZE_OFFSET);
if (rs != null)
{
rs.renderFileHandler.write(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data);
@@ -89,18 +89,6 @@ public class DhChunkPos {
return new DhBlockPos2D(x<<4, z<<4);
}
@Deprecated
public int getRegionX()
{
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, x, LodUtil.REGION_DETAIL_LEVEL);
}
@Deprecated
public int getRegionZ()
{
return LevelPosUtil.convert(LodUtil.CHUNK_DETAIL_LEVEL, z, LodUtil.REGION_DETAIL_LEVEL);
}
public long getLong() {
return toLong(x, z);
}
@@ -137,7 +137,7 @@ public class DhLodPos implements Comparable<DhLodPos>
}
DhLodPos lodPos = new DhLodPos(this.detailLevel, this.x, this.z);
lodPos = lodPos.convertUpwardsTo(sectionDetailLevel);
lodPos = lodPos.convertToDetailLevel(sectionDetailLevel);
return new DhSectionPos(lodPos.detailLevel, lodPos.x, lodPos.z);
}
@@ -147,13 +147,21 @@ public class DhLodPos implements Comparable<DhLodPos>
// methods //
//=========//
/** Only works for newDetailLevel's that are greater than or equal to this position's detailLevel */
public DhLodPos convertUpwardsTo(byte newDetailLevel)
/** Returns a new DhLodPos with the given detail level. */
public DhLodPos convertToDetailLevel(byte newDetailLevel)
{
LodUtil.assertTrue(newDetailLevel >= this.detailLevel);
return new DhLodPos(newDetailLevel,
Math.floorDiv(this.x, BitShiftUtil.powerOfTwo(newDetailLevel - this.detailLevel)),
Math.floorDiv(this.z, BitShiftUtil.powerOfTwo(newDetailLevel - this.detailLevel)));
if (newDetailLevel >= this.detailLevel)
{
return new DhLodPos(newDetailLevel,
Math.floorDiv(this.x, BitShiftUtil.powerOfTwo(newDetailLevel - this.detailLevel)),
Math.floorDiv(this.z, BitShiftUtil.powerOfTwo(newDetailLevel - this.detailLevel)));
}
else
{
return new DhLodPos(newDetailLevel,
this.x * BitShiftUtil.powerOfTwo(this.detailLevel - newDetailLevel),
this.z * BitShiftUtil.powerOfTwo(this.detailLevel - newDetailLevel));
}
}
public boolean overlaps(DhLodPos other)
@@ -165,11 +173,11 @@ public class DhLodPos implements Comparable<DhLodPos>
if (this.detailLevel > other.detailLevel)
{
return this.equals(other.convertUpwardsTo(this.detailLevel));
return this.equals(other.convertToDetailLevel(this.detailLevel));
}
else
{
return other.equals(this.convertUpwardsTo(other.detailLevel));
return other.equals(this.convertToDetailLevel(other.detailLevel));
}
}
@@ -3,7 +3,6 @@ package com.seibel.lod.core.pos;
import com.seibel.lod.core.enums.ELodDirection;
import com.seibel.lod.core.util.BitShiftUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.util.MathUtil;
import java.util.function.Consumer;
@@ -50,7 +49,7 @@ public class DhSectionPos
public DhSectionPos(DhBlockPos blockPos)
{
DhLodPos lodPos = new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPos.x, blockPos.z);
lodPos = lodPos.convertUpwardsTo(SECTION_BLOCK_DETAIL_LEVEL);
lodPos = lodPos.convertToDetailLevel(SECTION_BLOCK_DETAIL_LEVEL);
this.sectionDetail = SECTION_BLOCK_DETAIL_LEVEL;
this.sectionX = lodPos.x;
@@ -60,7 +59,7 @@ public class DhSectionPos
public DhSectionPos(DhChunkPos chunkPos)
{
DhLodPos lodPos = new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkPos.x, chunkPos.z);
lodPos = lodPos.convertUpwardsTo(SECTION_CHUNK_DETAIL_LEVEL);
lodPos = lodPos.convertToDetailLevel(SECTION_CHUNK_DETAIL_LEVEL);
this.sectionDetail = SECTION_CHUNK_DETAIL_LEVEL;
this.sectionX = lodPos.x;
@@ -58,21 +58,6 @@ public class LevelPosUtil
return new int[] { detailLevel, posX, posZ };
}
public static int convert(byte detailLevel, int pos, byte newDetailLevel)
{
int width;
if (newDetailLevel >= detailLevel)
{
width = 1 << (newDetailLevel - detailLevel);
return Math.floorDiv(pos, width);
}
else
{
width = 1 << (detailLevel - newDetailLevel);
return pos * width;
}
}
public static int getRegion(byte detailLevel, int pos)
{
return Math.floorDiv(pos, 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel));
@@ -145,11 +130,6 @@ public class LevelPosUtil
return Math.floorDiv(getPosZ(levelPos), width);
}
public static int getChunkPos(byte detailLevel, int pos)
{
return convert(detailLevel, pos, LodUtil.CHUNK_DETAIL_LEVEL);
}
public static double centerDistance(byte detailLevel, int posX, int posZ, int playerPosX, int playerPosZ) {
int width = 1 << detailLevel;
double cPosX = posX * width + width/2.;
@@ -40,15 +40,7 @@ public interface IChunkWrapper extends IBindable
// FIXME: getHeightMapValue & getMaxY is the same! Which one to keep?
int getHeightMapValue(int xRel, int zRel);
int getMaxY(int x, int z);
@Deprecated
int getChunkPosX();
@Deprecated
int getChunkPosZ();
@Deprecated
int getRegionPosX();
@Deprecated
int getRegionPosZ();
int getMaxX();
int getMaxZ();
int getMinX();