package net.minecraft.client.renderer.debug; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.blaze3d.vertex.VertexConsumer; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.Octree; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.ShapeRenderer; import net.minecraft.client.renderer.culling.Frustum; import net.minecraft.util.Mth; import net.minecraft.world.phys.AABB; import org.apache.commons.lang3.mutable.MutableInt; @Environment(EnvType.CLIENT) public class OctreeDebugRenderer { private final Minecraft minecraft; public OctreeDebugRenderer(Minecraft minecraft) { this.minecraft = minecraft; } public void render(PoseStack poseStack, Frustum frustum, MultiBufferSource bufferSource, double camX, double camY, double camZ) { Octree octree = this.minecraft.levelRenderer.getSectionOcclusionGraph().getOctree(); MutableInt mutableInt = new MutableInt(0); octree.visitNodes((node, bl, i, bl2) -> this.renderNode(node, poseStack, bufferSource, camX, camY, camZ, i, bl, mutableInt, bl2), frustum, 32); } private void renderNode( Octree.Node node, PoseStack poseStack, MultiBufferSource bufferSource, double camX, double camY, double camZ, int recursionDepth, boolean isLeafNode, MutableInt nodesRendered, boolean isNearby ) { AABB aABB = node.getAABB(); double d = aABB.getXsize(); long l = Math.round(d / 16.0); if (l == 1L) { nodesRendered.add(1); double e = aABB.getCenter().x; double f = aABB.getCenter().y; double g = aABB.getCenter().z; int i = isNearby ? -16711936 : -1; DebugRenderer.renderFloatingText(poseStack, bufferSource, String.valueOf(nodesRendered.getValue()), e, f, g, i, 0.3F); } VertexConsumer vertexConsumer = bufferSource.getBuffer(RenderType.lines()); long m = l + 5L; ShapeRenderer.renderLineBox( poseStack, vertexConsumer, aABB.deflate(0.1 * recursionDepth).move(-camX, -camY, -camZ), getColorComponent(m, 0.3F), getColorComponent(m, 0.8F), getColorComponent(m, 0.5F), isLeafNode ? 0.4F : 1.0F ); } private static float getColorComponent(long value, float multiplier) { float f = 0.1F; return Mth.frac(multiplier * (float)value) * 0.9F + 0.1F; } }