Add DhLodPos getSectionRelative and getSectionPos methods

This commit is contained in:
James Seibel
2022-11-12 20:12:18 -06:00
parent 3dfaed4409
commit 51601e710a
2 changed files with 88 additions and 36 deletions
@@ -14,7 +14,6 @@ import com.seibel.lod.core.level.IDhLevel;
import com.seibel.lod.core.pos.DhBlockPos;
import com.seibel.lod.core.pos.DhLodPos;
import com.seibel.lod.core.pos.DhSectionPos;
import com.seibel.lod.core.util.BitShiftUtil;
import com.seibel.lod.core.util.ColorUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper;
@@ -44,7 +43,7 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
private static final Logger LOGGER = LogManager.getLogger(DhApiTerrainDataRepo.class.getSimpleName());
// debugging values
private static final Lock debugThreadLock = new ReentrantLock();
private static volatile boolean debugThreadRunning = false;
private static String currentDebugBiomeName = "";
private static int currentDebugBlockColorInt = -1;
@@ -97,8 +96,10 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
{
IMinecraftClientWrapper mcClientWrapper = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
if (debugThreadLock.tryLock())
if (!debugThreadRunning)
{
debugThreadRunning = true;
// thread to prevent locking up the render thread
Thread thread = new Thread(() ->
{
@@ -107,28 +108,10 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
IDhLevel level = SharedApi.currentWorld.getLevel(levelWrapper);
DhClientServerLevel serverLevel = (DhClientServerLevel) level;
int xBlockPos = blockPos.x;
int zBlockPos = blockPos.z;
DhLodPos inputPos = new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPos.x, blockPos.z);
byte inputDetailLevel = LodUtil.BLOCK_DETAIL_LEVEL;
byte outputDetailLevel = LodUtil.CHUNK_DETAIL_LEVEL;
byte detailLevelDifference = (byte) (outputDetailLevel - inputDetailLevel);
DhLodPos lodPos = new DhLodPos(inputDetailLevel, xBlockPos, zBlockPos);
lodPos = lodPos.convertUpwardsTo((byte) (DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL + detailLevelDifference));
DhSectionPos sectionPos = new DhSectionPos(lodPos.detailLevel, lodPos.x, lodPos.z);
// negative values need to be offset by the detail level difference
// in order to skip over -0 (relative position) to -1 (relative position)
int blockOffset = BitShiftUtil.powerOfTwo(detailLevelDifference) - 1;
xBlockPos += xBlockPos < 0 ? -blockOffset : 0;
zBlockPos += zBlockPos < 0 ? -blockOffset : 0;
int xRelativePos = xBlockPos / BitShiftUtil.powerOfTwo(detailLevelDifference);
int zRelativePos = zBlockPos / BitShiftUtil.powerOfTwo(detailLevelDifference);
xRelativePos = xBlockPos >= 0 ? (xRelativePos % 64) : 64 + (xRelativePos % 64);
zRelativePos = zBlockPos >= 0 ? (zRelativePos % 64) : 64 + (zRelativePos % 64);
DhSectionPos sectionPos = inputPos.getSectionPosWithSectionDetailLevel(DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL);
DhLodPos relativePos = inputPos.getDhSectionRelativePositionForDetailLevel(LodUtil.BLOCK_DETAIL_LEVEL);
// attempt to get the data source for this section
@@ -137,7 +120,7 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
{
// attempt to get the LOD data from the data source
FullDataPointIdMap mapping = dataSource.getMapping();
SingleFullArrayView dataColumn = dataSource.tryGet(xRelativePos, zRelativePos);
SingleFullArrayView dataColumn = dataSource.tryGet(relativePos.x, relativePos.z);
if (dataColumn == null)
{
logBlockBiomeDebugInfoIfDifferent("", -1);
@@ -185,14 +168,14 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
}
finally
{
debugThreadLock.unlock();
debugThreadRunning = false;
}
});
thread.start();
}
}
/** only logs the data if it was different than the currently stored debug data */
/** only logs the data if it was different vs the currently stored debug data */
private static void logBlockBiomeDebugInfoIfDifferent(ILevelWrapper levelWrapper, DhBlockPos blockPos, long dataPoint, FullDataPointIdMap mapping)
{
int id = FullDataPoint.getId(dataPoint);
@@ -204,7 +187,7 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo
int newBlockColorInt = ((IClientLevelWrapper)levelWrapper).computeBaseColor(blockPos, biome, blockState);
logBlockBiomeDebugInfoIfDifferent(newBiomeName, newBlockColorInt);
}
/** only logs the data if it was different than the currently stored debug data */
/** only logs the data if it was different vs the currently stored debug data */
private static void logBlockBiomeDebugInfoIfDifferent(String newBiomeName, int newBlockColorInt)
{
if (!currentDebugBiomeName.equals(newBiomeName) || currentDebugBlockColorInt != newBlockColorInt)
@@ -1,5 +1,6 @@
package com.seibel.lod.core.pos;
import com.seibel.lod.core.datatype.ILodDataSource;
import com.seibel.lod.core.util.BitShiftUtil;
import com.seibel.lod.core.util.LodUtil;
import org.jetbrains.annotations.NotNull;
@@ -29,6 +30,10 @@ public class DhLodPos implements Comparable<DhLodPos>
//=========//
// getters //
//=========//
public DhLodUnit getX() { return new DhLodUnit(this.detailLevel, this.x); }
public DhLodUnit getZ() { return new DhLodUnit(this.detailLevel, this.z); }
@@ -55,14 +60,6 @@ public class DhLodPos implements Comparable<DhLodPos>
this.z * BitShiftUtil.powerOfTwo(this.detailLevel - newDetail));
}
public DhLodPos convertUpwardsTo(byte newDetail)
{
LodUtil.assertTrue(newDetail >= this.detailLevel);
return new DhLodPos(newDetail,
Math.floorDiv(this.x, BitShiftUtil.powerOfTwo(newDetail - this.detailLevel)),
Math.floorDiv(this.z, BitShiftUtil.powerOfTwo(newDetail - this.detailLevel)));
}
/**
* Returns the DhLodPos 1 detail level lower <br><br>
*
@@ -88,6 +85,74 @@ public class DhLodPos implements Comparable<DhLodPos>
/** Returns this position's child index in its parent */
public int getChildIndexOfParent() { return (this.x & 1) + BitShiftUtil.square(this.z & 1); }
/**
* Returns a DhLodPos with the given detail level and an X/Z position somewhere between (0,0) and (63,63).
* This is done to access specific sections from a {@link ILodDataSource} where LOD columns are stored
* in 64 x 64 blocks.
*
* @throws IllegalArgumentException if this position's detail level is lower than the output detail level
*/
public DhLodPos getDhSectionRelativePositionForDetailLevel(byte outputDetailLevel) throws IllegalArgumentException
{
int xInput = this.x;
int zInput = this.z;
byte detailLevelDifference = (byte) (outputDetailLevel - this.detailLevel);
if (outputDetailLevel < this.detailLevel)
{
throw new IllegalArgumentException("The output Detail Level [" + outputDetailLevel + "] is less than this " + DhLodPos.class.getSimpleName() + "'s detail level [" + this.detailLevel + "].");
}
// negative values need to be offset by the detail level difference squared (in blocks)
// to skip over -0 (relative position) to -1 (relative position)
int blockOffset = BitShiftUtil.powerOfTwo(detailLevelDifference) - 1;
xInput += xInput < 0 ? -blockOffset : 0;
zInput += zInput < 0 ? -blockOffset : 0;
// convert the input positions into the new detail level
int xRelativePos = xInput / BitShiftUtil.powerOfTwo(detailLevelDifference);
int zRelativePos = zInput / BitShiftUtil.powerOfTwo(detailLevelDifference);
// convert the positions into section relative space (0-63)
xRelativePos = xInput >= 0 ? (xRelativePos % 64) : 64 + (xRelativePos % 64);
zRelativePos = zInput >= 0 ? (zRelativePos % 64) : 64 + (zRelativePos % 64);
return new DhLodPos(outputDetailLevel, xRelativePos, zRelativePos);
}
/**
* @param sectionDetailLevel This is different from the normal LOD Detail level, see {@link DhSectionPos} for more information
* @throws IllegalArgumentException if this position's detail level is lower than the output detail level
*/
public DhSectionPos getSectionPosWithSectionDetailLevel(byte sectionDetailLevel) throws IllegalArgumentException
{
if (sectionDetailLevel < this.detailLevel)
{
throw new IllegalArgumentException("The section Detail Level [" + sectionDetailLevel + "] is less than this " + DhLodPos.class.getSimpleName() + "'s detail level [" + this.detailLevel + "].");
}
DhLodPos lodPos = new DhLodPos(this.detailLevel, this.x, this.z);
lodPos = lodPos.convertUpwardsTo(sectionDetailLevel);
return new DhSectionPos(lodPos.detailLevel, lodPos.x, lodPos.z);
}
//=========//
// methods //
//=========//
/** Only works for newDetailLevel's that are greater than or equal to this position's detailLevel */
public DhLodPos convertUpwardsTo(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)));
}
public boolean overlaps(DhLodPos other)
{
if (this.equals(other))
@@ -121,6 +186,10 @@ public class DhLodPos implements Comparable<DhLodPos>
//===========//
// overrides //
//===========//
@Override
public boolean equals(Object obj)
{