package net.minecraft.client.renderer.debug; import com.google.common.collect.Maps; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import java.util.HashMap; import java.util.List; import java.util.Map; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShapeRenderer; import net.minecraft.core.BlockPos; import net.minecraft.network.protocol.common.custom.StructuresDebugPayload.PieceInfo; import net.minecraft.resources.ResourceKey; import net.minecraft.world.level.Level; import net.minecraft.world.level.levelgen.structure.BoundingBox; @Environment(EnvType.CLIENT) public class StructureRenderer implements DebugRenderer.SimpleDebugRenderer { private final Minecraft minecraft; private final Map, Map> postMainBoxes = Maps., Map>newIdentityHashMap(); private final Map, Map> postPieces = Maps., Map>newIdentityHashMap(); private static final int MAX_RENDER_DIST = 500; public StructureRenderer(Minecraft minecraft) { this.minecraft = minecraft; } @Override public void render(PoseStack poseStack, MultiBufferSource bufferSource, double camX, double camY, double camZ) { Camera camera = this.minecraft.gameRenderer.getMainCamera(); ResourceKey resourceKey = this.minecraft.level.dimension(); BlockPos blockPos = BlockPos.containing(camera.getPosition().x, 0.0, camera.getPosition().z); VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.lines()); if (this.postMainBoxes.containsKey(resourceKey)) { for (BoundingBox boundingBox : ((Map)this.postMainBoxes.get(resourceKey)).values()) { if (blockPos.closerThan(boundingBox.getCenter(), 500.0)) { ShapeRenderer.renderLineBox( poseStack, vertexConsumer, boundingBox.minX() - camX, boundingBox.minY() - camY, boundingBox.minZ() - camZ, boundingBox.maxX() + 1 - camX, boundingBox.maxY() + 1 - camY, boundingBox.maxZ() + 1 - camZ, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F, 1.0F ); } } } Map map = (Map)this.postPieces.get(resourceKey); if (map != null) { for (PieceInfo pieceInfo : map.values()) { BoundingBox boundingBox2 = pieceInfo.boundingBox(); if (blockPos.closerThan(boundingBox2.getCenter(), 500.0)) { if (pieceInfo.isStart()) { ShapeRenderer.renderLineBox( poseStack, vertexConsumer, boundingBox2.minX() - camX, boundingBox2.minY() - camY, boundingBox2.minZ() - camZ, boundingBox2.maxX() + 1 - camX, boundingBox2.maxY() + 1 - camY, boundingBox2.maxZ() + 1 - camZ, 0.0F, 1.0F, 0.0F, 1.0F, 0.0F, 1.0F, 0.0F ); } else { ShapeRenderer.renderLineBox( poseStack, vertexConsumer, boundingBox2.minX() - camX, boundingBox2.minY() - camY, boundingBox2.minZ() - camZ, boundingBox2.maxX() + 1 - camX, boundingBox2.maxY() + 1 - camY, boundingBox2.maxZ() + 1 - camZ, 0.0F, 0.0F, 1.0F, 1.0F, 0.0F, 0.0F, 1.0F ); } } } } } public void addBoundingBox(BoundingBox boundingBox, List pieces, ResourceKey dimension) { ((Map)this.postMainBoxes.computeIfAbsent(dimension, resourceKey -> new HashMap())).put(boundingBox.toString(), boundingBox); Map map = (Map)this.postPieces.computeIfAbsent(dimension, resourceKey -> new HashMap()); for (PieceInfo pieceInfo : pieces) { map.put(pieceInfo.boundingBox().toString(), pieceInfo); } } @Override public void clear() { this.postMainBoxes.clear(); this.postPieces.clear(); } }