From d31013a680904cdf8beb7f41c6e796a1e48e2e22 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Mon, 14 Nov 2022 21:40:40 -0600 Subject: [PATCH] Make the API TerrainRepo return all blocks in a given section instead of a single column --- .../data/IDhApiTerrainDataRepo.java | 28 +++++-- .../methods/data/DhApiTerrainDataRepo.java | 74 +++++++++++++++---- .../lod/core/api/internal/ClientApi.java | 6 +- 3 files changed, 85 insertions(+), 23 deletions(-) diff --git a/api/src/main/java/com/seibel/lod/api/interfaces/data/IDhApiTerrainDataRepo.java b/api/src/main/java/com/seibel/lod/api/interfaces/data/IDhApiTerrainDataRepo.java index bf1e0bf87..14b09a5dd 100644 --- a/api/src/main/java/com/seibel/lod/api/interfaces/data/IDhApiTerrainDataRepo.java +++ b/api/src/main/java/com/seibel/lod/api/interfaces/data/IDhApiTerrainDataRepo.java @@ -5,28 +5,42 @@ import com.seibel.lod.api.objects.DhApiResult; import com.seibel.lod.api.objects.data.DhApiTerrainDataPoint; /** + * Used to interface with Distant Horizons' terrain data. + * * @author James Seibel - * @version 2022-11-13 + * @version 2022-11-14 */ public interface IDhApiTerrainDataRepo { /** Returns the terrain datapoint at the given block position, at or containing the given Y position. */ DhApiResult getSingleDataPointAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosY, int blockPosZ); - /** Returns every datapoint in the column located at the given block X and Z position. */ + /** Returns every datapoint in the column located at the given block X and Z position top to bottom. */ DhApiResult getColumnDataAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosZ); // /** Sets the terrain data at the given block position. */ // DhApiResult setDataAtBlockPos(int blockPosX, int blockPosY, int blockPosZ, DhApiTerrainDataPoint newData); - /** Returns every datapoint in the column located at the given chunk X and Z position. */ - DhApiResult getColumnDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ); + /** + * Returns every datapoint in the given chunk's X and Z position.

+ * + * The returned array is ordered: [relativeBlockX][relativeBlockZ][columnIndex]
+ * RelativeBlockX/Z are relative to the block position closest to negative infinity in the chunk's position.
+ * The column data is ordered from top to bottom. Note: each column may have a different number of values.
+ */ + DhApiResult getAllTerrainDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ); // /** Sets the terrain data at the given chunk position. */ // DhApiResult setDataAtChunkPos(int chunkPosX, int chunkPosZ, DhApiTerrainDataPoint newData); - /** Returns every datapoint in the column located at the given region X and Z position. */ - DhApiResult getColumnDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ); + /** + * Returns every datapoint in the given region's X and Z position.

+ * + * The returned array is ordered: [relativeBlockX][relativeBlockZ][columnIndex]
+ * RelativeBlockX/Z are relative to the block position closest to negative infinity in the region's position.
+ * The column data is ordered from top to bottom. Note: each column may have a different number of values.
+ */ + DhApiResult getAllTerrainDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ); // /** Sets the terrain data at the given chunk position. */ // DhApiResult setDataAtRegionPos(int regionPosX, int regionPosZ, DhApiTerrainDataPoint newData); @@ -39,7 +53,7 @@ public interface IDhApiTerrainDataRepo * Every increase doubles the width of the returned area.
* Example values: 0 = block, 1 = 2x2 blocks, 2 = 4x4 blocks, ... 4 = chunk (16x16 blocks), ... 9 = region (512x512 blocks) */ - DhApiResult getColumnDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ); + DhApiResult getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ); // /** Sets the terrain data at the given chunk position. */ // DhApiResult setDataAtRegionPos(short detailLevel, int relativePosX, int relativePosY, int relativePosZ, DhApiTerrainDataPoint newData); 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 ea320e842..d3a160b10 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 @@ -15,8 +15,10 @@ 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.util.math.Vec3f; import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; @@ -30,10 +32,10 @@ import java.util.concurrent.ExecutionException; /** - * Allows getting and setting any terrain data Distant Horizons has stored. + * Allows interfacing with the terrain data Distant Horizons has stored. * * @author James Seibel - * @version 2022-11-13 + * @version 2022-11-14 */ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo { @@ -63,32 +65,32 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo @Override public DhApiResult getColumnDataAtBlockPos(IDhApiLevelWrapper levelWrapper, int blockPosX, int blockPosZ) { - return getTerrainDataArray(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), null); + return getTerrainDataColumnArray(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), null); } // @Override // public DhApiResult setDataAtBlockPos(int blockPosX, int blockPosY, int blockPosZ, DhApiTerrainDataPoint newData) { throw new UnsupportedOperationException(); } @Override - public DhApiResult getColumnDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ) + public DhApiResult getAllTerrainDataAtChunkPos(IDhApiLevelWrapper levelWrapper, int chunkPosX, int chunkPosZ) { - return getTerrainDataArray(levelWrapper, new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkPosX, chunkPosZ), null); + return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkPosX, chunkPosZ)); } // @Override // public DhApiResult setDataAtChunkPos(int chunkPosX, int chunkPosZ, DhApiTerrainDataPoint newData) { throw new UnsupportedOperationException(); } @Override - public DhApiResult getColumnDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ) + public DhApiResult getAllTerrainDataAtRegionPos(IDhApiLevelWrapper levelWrapper, int regionPosX, int regionPosZ) { - return getTerrainDataArray(levelWrapper, new DhLodPos(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ), null); + return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, new DhLodPos(LodUtil.REGION_DETAIL_LEVEL, regionPosX, regionPosZ)); } // @Override // public DhApiResult setDataAtRegionPos(int regionPosX, int regionPosZ, DhApiTerrainDataPoint newData) { throw new UnsupportedOperationException(); } @Override - public DhApiResult getColumnDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ) + public DhApiResult getAllTerrainDataAtDetailLevelAndPos(IDhApiLevelWrapper levelWrapper, byte detailLevel, int posX, int posZ) { - return getTerrainDataArray(levelWrapper, new DhLodPos(detailLevel, posX, posZ), null); + return getTerrainDataOverAreaForPositionDetailLevel(levelWrapper, new DhLodPos(detailLevel, posX, posZ)); } // @Override // public DhApiResult setDataAtRegionPos(short detailLevel, int relativePosX, int relativePosY, int relativePosZ, DhApiTerrainDataPoint newData) { throw new UnsupportedOperationException(); } @@ -102,7 +104,7 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo /** Returns a single API terrain datapoint that contains the given Y block position */ private static DhApiResult getTerrainDataAtBlockYPos(IDhApiLevelWrapper levelWrapper, DhLodPos requestedColumnPos, Integer blockYPos) { - DhApiResult result = getTerrainDataArray(levelWrapper, requestedColumnPos, blockYPos); + DhApiResult result = getTerrainDataColumnArray(levelWrapper, requestedColumnPos, blockYPos); if (result.success && result.payload.length > 0) { return DhApiResult.createSuccess(result.errorMessage, result.payload[0]); @@ -113,13 +115,52 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo } } + /** + * Returns all the block columns represented by the given {@link DhLodPos}.
+ * IE, A position with the detail level:
+ * 0 (block): will return a 1x1 matrix of data. (don't do this, we have a specific method for that.)
+ * 1 (2 blocks): will return a 2x2 matrix of data.
+ * 4 (chunk): will return a 16x16 matrix of data.

+ * + * will stop and return the in progress data if any errors are encountered. + */ + private static DhApiResult getTerrainDataOverAreaForPositionDetailLevel(IDhApiLevelWrapper levelWrapper, DhLodPos requestedAreaPos) + { + DhLodPos startingBlockPos = requestedAreaPos.getCorner(LodUtil.BLOCK_DETAIL_LEVEL); + int widthOfAreaInBlocks = BitShiftUtil.powerOfTwo(requestedAreaPos.detailLevel); + + DhApiTerrainDataPoint[][][] returnArray = new DhApiTerrainDataPoint[widthOfAreaInBlocks][widthOfAreaInBlocks][]; + int dataColumnsReturned = 0; + + // get each column over the area + for (var x = 0; x < widthOfAreaInBlocks; x++) + { + for (var z = 0; z < widthOfAreaInBlocks; z++) + { + DhLodPos blockColumnPos = new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, startingBlockPos.x + x, startingBlockPos.z + z); + DhApiResult result = getTerrainDataColumnArray(levelWrapper, blockColumnPos, null); + if (result.success) + { + returnArray[x][z] = result.payload; + dataColumnsReturned++; + } + else + { + return DhApiResult.createFail(result.errorMessage, returnArray); + } + } + } + + return dataColumnsReturned != 0 ? DhApiResult.createSuccess("[" + dataColumnsReturned + "] columns returned.", returnArray) : DhApiResult.createSuccess("No data found.", returnArray); + } + /** * 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. */ - private static DhApiResult getTerrainDataArray(IDhApiLevelWrapper levelWrapper, DhLodPos requestedColumnPos, Integer nullableBlockYPos) + private static DhApiResult getTerrainDataColumnArray(IDhApiLevelWrapper levelWrapper, DhLodPos requestedColumnPos, Integer nullableBlockYPos) { if (SharedApi.currentWorld == null) { @@ -137,8 +178,6 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo { return DhApiResult.createFail("Unable to get terrain data before the world has loaded."); } -// DhClientServerLevel serverLevel = (DhClientServerLevel) level; -// IDhLevel serverLevel = (IDhLevel) level; // get the detail levels for this request byte requestedDetailLevel = requestedColumnPos.detailLevel; @@ -249,8 +288,13 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo Thread thread = new Thread(() -> { try { - DhApiResult x = getTerrainDataAtBlockYPos(levelWrapper, new DhLodPos(LodUtil.BLOCK_DETAIL_LEVEL, blockPosX, blockPosZ), blockPosY); - DhApiResult y = getTerrainDataArray(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); + + int debugPoint = 0; } catch (Exception e) { diff --git a/core/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java index e790bd883..3b26e6806 100644 --- a/core/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java @@ -22,6 +22,7 @@ package com.seibel.lod.core.api.internal; import com.seibel.lod.api.methods.events.abstractEvents.*; import com.seibel.lod.api.methods.events.sharedParameterObjects.DhApiRenderParam; import com.seibel.lod.core.DependencyInjection.DhApiEventInjector; +import com.seibel.lod.core.api.external.methods.data.DhApiTerrainDataRepo; import com.seibel.lod.core.level.IDhClientLevel; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.ModInfo; @@ -49,7 +50,6 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.glfw.GLFW; -import java.time.Duration; import java.util.concurrent.TimeUnit; /** @@ -237,6 +237,10 @@ public class ClientApi } + DhApiTerrainDataRepo.asyncDebugMethod(levelWrapper, MC.getPlayerBlockPos().x, MC.getPlayerBlockPos().y, MC.getPlayerBlockPos().z); + + + profiler.push("Render" + ( Config.Client.Advanced.Debugging.rendererMode.get() == ERendererMode.DEFAULT ? "-lods" : "-debug")); try {