diff --git a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java index 2e4253df0..2c62fcb4a 100644 --- a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java +++ b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java @@ -178,7 +178,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider while (--sectionDetail >= this.minDetailLevel) { DhLodPos minPos = pos.getCorner().getCornerLodPos(sectionDetail); - int count = pos.getSectionBBoxPos().getBlockWidth(sectionDetail); + int count = pos.getSectionBBoxPos().getWidthAtDetail(sectionDetail); for (int xOffset = 0; xOffset < count; xOffset++) { diff --git a/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java b/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java index 6eb15d9e7..aefc995d1 100644 --- a/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java +++ b/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java @@ -10,6 +10,8 @@ import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.file.fullDatafile.FullDataFileHandler; import com.seibel.lod.core.generation.tasks.*; import com.seibel.lod.core.pos.*; +import com.seibel.lod.core.render.renderer.DebugRenderer; +import com.seibel.lod.core.render.renderer.IDebugRenderable; import com.seibel.lod.core.util.ThreadUtil; import com.seibel.lod.core.util.objects.quadTree.QuadNode; import com.seibel.lod.core.util.objects.quadTree.QuadTree; @@ -20,12 +22,13 @@ import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import org.apache.logging.log4j.Logger; +import java.awt.*; import java.io.Closeable; import java.util.*; import java.util.concurrent.*; import java.util.function.Consumer; -public class WorldGenerationQueue implements Closeable +public class WorldGenerationQueue implements Closeable, IDebugRenderable { private static final Logger LOGGER = DhLoggerBuilder.getLogger(); @@ -95,6 +98,7 @@ public class WorldGenerationQueue implements Closeable { throw new IllegalArgumentException(IDhApiWorldGenerator.class.getSimpleName() + ": max granularity smaller than min granularity!"); } + DebugRenderer.register(this); } @@ -242,7 +246,9 @@ public class WorldGenerationQueue implements Closeable // } // } // } - + + private final Set CheckingTasks = Collections.newSetFromMap(new ConcurrentHashMap<>()); + /** * @param targetPos the position to center the generation around * @return false if no tasks were found to generate @@ -252,6 +258,7 @@ public class WorldGenerationQueue implements Closeable long closestGenDist = Long.MAX_VALUE; WorldGenTask closestTask = null; + CheckingTasks.clear(); // TODO improve, having to go over every node isn't super efficient, removing null nodes from the tree would help Iterator> nodeIterator = this.waitingTaskQuadTree.nodeIterator(); @@ -263,6 +270,7 @@ public class WorldGenerationQueue implements Closeable if (newGenTask != null) // TODO add an option to skip leaves with null values and potentially auto-prune them { + CheckingTasks.add(newGenTask); // TODO this isn't a long term fix, in the long term the tree should automatically remove out of bound nodes when moved if (!this.waitingTaskQuadTree.isSectionPosInBounds(taskSectionPos)) { @@ -289,14 +297,10 @@ public class WorldGenerationQueue implements Closeable return false; } - - // remove the task we found, we are going to start it and don't want to run it multiple times // TODO the setValue can fail if the user is moving and the task that was once in range is no longer in range WorldGenTask removedWorldGenTask = this.waitingTaskQuadTree.setValue(new DhSectionPos(closestTask.pos.detailLevel, closestTask.pos.x, closestTask.pos.z), null); - - // do we need to modify this task to generate it? if(this.canGeneratePos((byte) 0, closestTask.pos)) // TODO should detail level 0 be replaced? { @@ -371,7 +375,6 @@ public class WorldGenerationQueue implements Closeable DhChunkPos chunkPosMin = new DhChunkPos(taskPos.getCornerBlockPos()); - // check if this is a duplicate generation task if (this.alreadyGeneratedPosHashSet.contains(inProgressTaskGroup.group.pos)) { @@ -578,6 +581,8 @@ public class WorldGenerationQueue implements Closeable LOGGER.info("Finished closing "+WorldGenerationQueue.class.getSimpleName()); + + DebugRenderer.unregister(this); } @@ -616,6 +621,16 @@ public class WorldGenerationQueue implements Closeable return index; } - - + + + @Override + public void debugRender(DebugRenderer r) { + CheckingTasks.forEach((t) -> { + DhLodPos pos = t.pos; + r.renderBox(pos, -32f, 64f, 0.05f, Color.blue); + }); + this.inProgressGenTasksByLodPos.forEach((pos, t) -> { + r.renderBox(pos, -30f, 64f, 0.05f, Color.red); + }); + } } 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 0b591d6ad..83e8e3ea4 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 @@ -39,19 +39,22 @@ public class DhLodPos implements Comparable public DhLodUnit getX() { return new DhLodUnit(this.detailLevel, this.x); } public DhLodUnit getZ() { return new DhLodUnit(this.detailLevel, this.z); } - - public int getBlockWidth() { return this.getBlockWidth(this.detailLevel); } - public int getBlockWidth(byte detailLevel) // TODO this needs some documentation or a better name describing what is happening, why is there an assert here? + + // Get the width of this pos, measured in the mc block unit. (i.e. detail 0) + public int getBlockWidth() { return this.getWidthAtDetail((byte)0); } + + // Get the width of this pos, measured in the target detail level. + public int getWidthAtDetail(byte targetLevel) { - LodUtil.assertTrue(detailLevel <= this.detailLevel); - return BitShiftUtil.powerOfTwo(this.detailLevel - detailLevel); + LodUtil.assertTrue(targetLevel <= this.detailLevel); + return BitShiftUtil.powerOfTwo(this.detailLevel - targetLevel); } public DhBlockPos2D getCenterBlockPos() { return new DhBlockPos2D( this.getX().toBlockWidth() + BitShiftUtil.half(this.getBlockWidth()), - this.getZ().toBlockWidth() + BitShiftUtil.half(this.getBlockWidth())); + this.getZ().toBlockWidth() + BitShiftUtil.half(this.getBlockWidth())); } public DhBlockPos2D getCornerBlockPos() { return new DhBlockPos2D(this.getX().toBlockWidth(), this.getZ().toBlockWidth()); } diff --git a/core/src/main/java/com/seibel/lod/core/render/renderer/DebugRenderer.java b/core/src/main/java/com/seibel/lod/core/render/renderer/DebugRenderer.java index b87b9f369..b8ebf1c3e 100644 --- a/core/src/main/java/com/seibel/lod/core/render/renderer/DebugRenderer.java +++ b/core/src/main/java/com/seibel/lod/core/render/renderer/DebugRenderer.java @@ -7,9 +7,8 @@ import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.logging.ConfigBasedLogger; import com.seibel.lod.core.logging.ConfigBasedSpamLogger; import com.seibel.lod.core.pos.DhBlockPos2D; +import com.seibel.lod.core.pos.DhLodPos; import com.seibel.lod.core.pos.DhSectionPos; -import com.seibel.lod.core.render.LodRenderSection; -import com.seibel.lod.core.render.glObject.GLProxy; import com.seibel.lod.core.render.glObject.GLState; import com.seibel.lod.core.render.glObject.buffer.GLElementBuffer; import com.seibel.lod.core.render.glObject.buffer.GLVertexBuffer; @@ -144,17 +143,23 @@ public class DebugRenderer { private Mat4f transform_this_frame; private Vec3f camf; + public void renderBox(DhLodPos pos, float minY, float maxY, float marginPercent, Color color) { + DhBlockPos2D blockMin = pos.getCornerBlockPos(); + DhBlockPos2D blockMax = blockMin.add(pos.getBlockWidth(), pos.getBlockWidth()); + float edge = pos.getBlockWidth() * marginPercent; + renderBox(blockMin.x + edge, minY, blockMin.z + edge, blockMax.x - edge, maxY, blockMax.z - edge, color); + } + + public void renderBox(DhLodPos pos, float minY, float maxY, Color color) { + renderBox(pos, minY, maxY, 0, color); + } + public void renderBox(DhSectionPos sectPos, float minY, float maxY, Color color) { - DhBlockPos2D blockMin = sectPos.getCorner().getCornerBlockPos(); - DhBlockPos2D blockMax = blockMin.add(sectPos.getWidth().toBlockWidth(), sectPos.getWidth().toBlockWidth()); - renderBox(blockMin.x, minY, blockMin.z, blockMax.x, maxY, blockMax.z, color); + renderBox(sectPos.getSectionBBoxPos(), minY, maxY, 0, color); } public void renderBox(DhSectionPos sectPos, float minY, float maxY, float marginPercent, Color color) { - DhBlockPos2D blockMin = sectPos.getCorner().getCornerBlockPos(); - DhBlockPos2D blockMax = blockMin.add(sectPos.getWidth().toBlockWidth(), sectPos.getWidth().toBlockWidth()); - float edge = sectPos.getWidth().toBlockWidth() * marginPercent; - renderBox(blockMin.x + edge, minY, blockMin.z + edge, blockMax.x - edge, maxY, blockMax.z - edge, color); + renderBox(sectPos.getSectionBBoxPos(), minY, maxY, marginPercent, color); } public void renderBox(float x, float y, float z, float x2, float y2, float z2, Color color) {