From 51601e710a171fae0e7774f3f0d1797c43f7876e Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 12 Nov 2022 20:12:18 -0600 Subject: [PATCH] Add DhLodPos getSectionRelative and getSectionPos methods --- .../methods/data/DhApiTerrainDataRepo.java | 39 +++------ .../com/seibel/lod/core/pos/DhLodPos.java | 85 +++++++++++++++++-- 2 files changed, 88 insertions(+), 36 deletions(-) diff --git a/core/src/main/java/com/seibel/lod/core/api/external/methods/data/DhApiTerrainDataRepo.java b/core/src/main/java/com/seibel/lod/core/api/external/methods/data/DhApiTerrainDataRepo.java index f80f578fa..29b97d2b2 100644 --- a/core/src/main/java/com/seibel/lod/core/api/external/methods/data/DhApiTerrainDataRepo.java +++ b/core/src/main/java/com/seibel/lod/core/api/external/methods/data/DhApiTerrainDataRepo.java @@ -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) diff --git a/core/src/main/java/com/seibel/lod/core/pos/DhLodPos.java b/core/src/main/java/com/seibel/lod/core/pos/DhLodPos.java index edff272da..b7327cb13 100644 --- a/core/src/main/java/com/seibel/lod/core/pos/DhLodPos.java +++ b/core/src/main/java/com/seibel/lod/core/pos/DhLodPos.java @@ -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 + //=========// + // 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 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

* @@ -88,6 +85,74 @@ public class DhLodPos implements Comparable /** 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 + //===========// + // overrides // + //===========// + @Override public boolean equals(Object obj) {