From 103a03c90fb641e00a4d0ca1ccd736560c825717 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Wed, 16 Nov 2022 22:35:56 -0600 Subject: [PATCH] partially functional raycasting --- .../block/IDhApiBlockStateWrapper.java | 3 +- .../interfaces/world/IDhApiLevelWrapper.java | 5 + .../com/seibel/lod/core/util/math/Vec3f.java | 1 + .../methods/data/DhApiTerrainDataRepo.java | 92 ++++++++++++++++++- 4 files changed, 95 insertions(+), 6 deletions(-) diff --git a/api/src/main/java/com/seibel/lod/api/interfaces/block/IDhApiBlockStateWrapper.java b/api/src/main/java/com/seibel/lod/api/interfaces/block/IDhApiBlockStateWrapper.java index 8a183385a..d2660249c 100644 --- a/api/src/main/java/com/seibel/lod/api/interfaces/block/IDhApiBlockStateWrapper.java +++ b/api/src/main/java/com/seibel/lod/api/interfaces/block/IDhApiBlockStateWrapper.java @@ -10,5 +10,6 @@ import com.seibel.lod.api.interfaces.IDhApiUnsafeWrapper; */ public interface IDhApiBlockStateWrapper extends IDhApiUnsafeWrapper { - + boolean isAir(); + } diff --git a/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiLevelWrapper.java b/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiLevelWrapper.java index bbd497830..d0ed8ea6c 100644 --- a/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiLevelWrapper.java +++ b/api/src/main/java/com/seibel/lod/api/interfaces/world/IDhApiLevelWrapper.java @@ -38,8 +38,13 @@ public interface IDhApiLevelWrapper extends IDhApiUnsafeWrapper boolean hasSkyLight(); + /** Returns the max block height of the level(?) */ int getHeight(); + /** + * Returns the lowest possible block position for the level.
+ * For MC versions before 1.19 this will return 0. + */ default int getMinHeight() { return 0; } } diff --git a/api/src/main/java/com/seibel/lod/core/util/math/Vec3f.java b/api/src/main/java/com/seibel/lod/core/util/math/Vec3f.java index 4c50f1a92..063f84515 100644 --- a/api/src/main/java/com/seibel/lod/core/util/math/Vec3f.java +++ b/api/src/main/java/com/seibel/lod/core/util/math/Vec3f.java @@ -147,6 +147,7 @@ public class Vec3f return this.x * vector.x + this.y * vector.y + this.z * vector.z; } + /** Returns true if normalization had to be done */ public boolean normalize() { float squaredSum = this.x * this.x + this.y * this.y + this.z * this.z; 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 d3a160b10..e1a7c5c5f 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 @@ -18,12 +18,17 @@ 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.util.MathUtil; +import com.seibel.lod.core.util.math.Vec3d; import com.seibel.lod.core.util.math.Vec3f; +import com.seibel.lod.core.util.math.Vec3i; import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; 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 net.minecraft.client.Minecraft; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -47,6 +52,7 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo private static volatile boolean debugThreadRunning = false; private static String currentDebugBiomeName = ""; private static int currentDebugBlockColorInt = -1; + private static Vec3i currentDebugVec3i = new Vec3i(); @@ -56,6 +62,66 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo } + // TODO: this will need ot use API objects + public DhApiResult getLodPosFromRay(IDhApiLevelWrapper levelWrapper, DhBlockPos rayOrigin, Vec3f directionVector, byte detailLevel) + { + directionVector.normalize(); + + int minBlockHeight = levelWrapper.getMinHeight(); + int maxBlockHeight = levelWrapper.getHeight(); + int maxLength = 50; + + + + // walk through the grid // + + int currentLength = 0; + + Vec3d exactPos = new Vec3d(rayOrigin.x, rayOrigin.y, rayOrigin.z); + Vec3i blockPos = new Vec3i(rayOrigin.x, rayOrigin.y, rayOrigin.z); + + while (blockPos.y >= minBlockHeight && blockPos.y < maxBlockHeight + && currentLength <= maxLength) + { + // get the LOD at this position + DhApiResult result = this.getColumnDataAtBlockPos(levelWrapper, blockPos.x, blockPos.z); + if (!result.success) + { + // if there was an error, stop and return it + return DhApiResult.createFail(result.errorMessage); + } + + // is there a LOD at this position? + for (DhApiTerrainDataPoint dataPoint : result.payload) + { + // is this LOD air? + if (dataPoint.blockStateWrapper != null && !dataPoint.blockStateWrapper.isAir()) + { + // does this LOD contain the given Y position? + if (dataPoint.bottomYBlockPos <= exactPos.y && exactPos.y <= dataPoint.topYBlockPos) + { + return DhApiResult.createSuccess(blockPos); + } + } + } + + + exactPos.x += directionVector.x; + exactPos.y += directionVector.y; + exactPos.z += directionVector.z; + + blockPos.x = (int) Math.round(exactPos.x); + blockPos.y = (int) Math.round(exactPos.y); + blockPos.z = (int) Math.round(exactPos.z); + + // calculate the taxiCab Distance + currentLength = (int) (Math.abs(rayOrigin.x - exactPos.x) + Math.abs(rayOrigin.y - exactPos.y) + Math.abs(rayOrigin.z - exactPos.z)); + } + + return DhApiResult.createSuccess(null); + } + + @Override public DhApiResult getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ) @@ -158,7 +224,8 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo * If nullableBlockYPos is null: returns every datapoint in the column defined by the DhLodPos.
* If nullableBlockYPos is NOT null: returns a single datapoint in the column defined by the DhLodPos which contains the block Y position.

* - * Returns an empty array if no data could be returned. + * If the ApiResult is successful there will be an array of data.
+ * The returned array will be empty if no data could be retrieved. */ private static DhApiResult getTerrainDataColumnArray(IDhApiLevelWrapper levelWrapper, DhLodPos requestedColumnPos, Integer nullableBlockYPos) { @@ -288,11 +355,26 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo Thread thread = new Thread(() -> { try { - DhApiResult single = getTerrainDataAtBlockYPos(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), blockPosY); - DhApiResult column = getTerrainDataColumnArray(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), null); +// DhApiResult single = getTerrainDataAtBlockYPos(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), blockPosY); +// DhApiResult column = getTerrainDataColumnArray(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), null); + +// DhLodPos chunkPos = new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ).convertUpwardsTo(LodUtil.CHUNK_DETAIL_LEVEL); +// DhApiResult area = getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, chunkPos); + + + IMinecraftRenderWrapper MC_RENDER = SingletonInjector.INSTANCE.get(IMinecraftRenderWrapper.class); + DhApiResult rayCast = INSTANCE.getLodPosFromRay(levelWrapper, MC_RENDER.getCameraBlockPosition(), MC_RENDER.getLookAtVector(), LodUtil.BLOCK_DETAIL_LEVEL); + if (rayCast.payload != null && !rayCast.payload.equals(currentDebugVec3i)) + { + currentDebugVec3i = rayCast.payload; + LOGGER.info("raycast: " + currentDebugVec3i); + } + else if (rayCast.payload == null && currentDebugVec3i != null) + { + currentDebugVec3i = null; + LOGGER.info("raycast: [INFINITY]"); + } - DhLodPos chunkPos = new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ).convertUpwardsTo(LodUtil.CHUNK_DETAIL_LEVEL); - DhApiResult area = getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, chunkPos); int debugPoint = 0; }