From 6ac1c0e944071aa1ce8a2686996d00e6889501e9 Mon Sep 17 00:00:00 2001 From: SquidDev Date: Mon, 11 Feb 2019 09:05:27 +0000 Subject: [PATCH] Basic network visualiser --- .../client/render/RenderOverlayNetwork.java | 188 ++++++++++++++++++ 1 file changed, 188 insertions(+) create mode 100644 src/main/java/dan200/computercraft/client/render/RenderOverlayNetwork.java diff --git a/src/main/java/dan200/computercraft/client/render/RenderOverlayNetwork.java b/src/main/java/dan200/computercraft/client/render/RenderOverlayNetwork.java new file mode 100644 index 000000000..e7c68f4ef --- /dev/null +++ b/src/main/java/dan200/computercraft/client/render/RenderOverlayNetwork.java @@ -0,0 +1,188 @@ +package dan200.computercraft.client.render; + +import com.google.common.collect.Sets; +import dan200.computercraft.ComputerCraft; +import dan200.computercraft.api.network.wired.IWiredElement; +import dan200.computercraft.shared.wired.WiredNetwork; +import dan200.computercraft.shared.wired.WiredNode; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.renderer.BufferBuilder; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.vertex.DefaultVertexFormats; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; +import net.minecraft.world.World; +import net.minecraftforge.client.event.RenderWorldLastEvent; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import org.lwjgl.opengl.GL11; + +import java.awt.*; +import java.util.Collection; +import java.util.Set; + +/** + * This is a helper to render a network when testing. + */ +public final class RenderOverlayNetwork +{ + private int ticksInGame; + private IWiredElement element; + + @SubscribeEvent + public void onWorldRenderLast( RenderWorldLastEvent event ) + { + ++ticksInGame; + + RayTraceResult result = Minecraft.getMinecraft().objectMouseOver; + if( result != null && result.typeOfHit == RayTraceResult.Type.BLOCK ) + { + World clientWorld = Minecraft.getMinecraft().world; + World world = FMLCommonHandler.instance().getMinecraftServerInstance().getWorld( clientWorld.provider.getDimension() ); + + IWiredElement newElement = ComputerCraft.getWiredElementAt( world, result.getBlockPos(), result.sideHit ); + if( newElement != null ) element = newElement; + } + + if( element == null ) return; + + Minecraft minecraft = Minecraft.getMinecraft(); + ItemStack stack = minecraft.player.getHeldItemMainhand(); + ItemStack otherStack = minecraft.player.getHeldItemOffhand(); + + if( stack.getItem() != Items.STICK && otherStack.getItem() != Items.STICK ) return; + + GlStateManager.pushMatrix(); + RenderManager renderManager = minecraft.getRenderManager(); + GlStateManager.translate( -renderManager.viewerPosX, -renderManager.viewerPosY, -renderManager.viewerPosZ ); + + GlStateManager.disableDepth(); + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + GlStateManager.blendFunc( GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA ); + + Set> connections = Sets.newHashSet(); + WiredNetwork network = (WiredNetwork) element.getNode().getNetwork(); + + for( WiredNode node : network.getNodes() ) + { + for( WiredNode other : node.getNeighbours() ) + { + connections.add( new Pair<>( node.getElement(), other.getElement() ) ); + } + } + + renderNetworkConnections( connections, new Color( Color.HSBtoRGB( ticksInGame % 200 / 200F, 0.6F, 1F ) ), 1f ); + + GlStateManager.enableDepth(); + GlStateManager.enableTexture2D(); + GlStateManager.disableBlend(); + GlStateManager.popMatrix(); + } + + private void renderNetworkConnections( Collection> data, Color color, float thickness ) + { + renderConnections( data, color, 1.0f, thickness ); + renderConnections( data, color, 64.0f / 255.0f, thickness * 3 ); + } + + private void renderConnections( Collection> connections, Color color, float alpha, float thickness ) + { + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder renderer = tessellator.getBuffer(); + + GlStateManager.pushMatrix(); + GlStateManager.scale( 1, 1, 1 ); + + GlStateManager.color( color.getRed() / 255.0f, color.getGreen() / 255.0f, color.getBlue() / 255.0f, alpha ); + GL11.glLineWidth( thickness ); + + renderer.begin( GL11.GL_LINES, DefaultVertexFormats.POSITION ); + for( Pair connection : connections ) + { + Vec3d a = connection.x.getPosition(), b = connection.y.getPosition(); + + renderer.pos( a.x, a.y, a.z ).endVertex(); + renderer.pos( b.x, b.y, b.z ).endVertex(); + } + + tessellator.draw(); + + GlStateManager.popMatrix(); + } + + private void renderLabel( double x, double y, double z, String label ) + { + RenderManager renderManager = Minecraft.getMinecraft().getRenderManager(); + FontRenderer fontrenderer = renderManager.getFontRenderer(); + if( fontrenderer == null ) return; + + GlStateManager.pushMatrix(); + GlStateManager.disableLighting(); + + float scale = 0.02666667f; + GlStateManager.translate( x, y, z ); + GlStateManager.rotate( -renderManager.playerViewY, 0, 1, 0 ); + GlStateManager.rotate( renderManager.playerViewX, 1, 0, 0 ); + GlStateManager.scale( -scale, -scale, scale ); + + // Render label background + Tessellator tessellator = Tessellator.getInstance(); + BufferBuilder renderer = tessellator.getBuffer(); + + int width = fontrenderer.getStringWidth( label ); + int xOffset = width / 2; + + GlStateManager.disableTexture2D(); + GlStateManager.color( 0, 0, 0, 65 / 225.0f ); + + renderer.begin( GL11.GL_QUADS, DefaultVertexFormats.POSITION ); + renderer.pos( -xOffset - 1, -1, 0 ).endVertex(); + renderer.pos( -xOffset - 1, 8, 0 ).endVertex(); + renderer.pos( xOffset + 1, 8, 0 ).endVertex(); + renderer.pos( xOffset + 1, -1, 0 ).endVertex(); + + tessellator.draw(); + GlStateManager.enableTexture2D(); + + // Render label + fontrenderer.drawString( label, -width / 2, 0, 0xFFFFFFFF ); + + GlStateManager.enableLighting(); + GlStateManager.popMatrix(); + } + + private static class Pair + { + public final T x; + public final T y; + + public Pair( T right, T y ) + { + this.x = right; + this.y = y; + } + + @Override + public boolean equals( Object o ) + { + if( this == o ) return true; + if( o == null || getClass() != o.getClass() ) return false; + + Pair p = (Pair) o; + return (x.equals( p.x ) && y.equals( p.y )) + || (x.equals( p.y ) && y.equals( p.x )); + } + + @Override + public int hashCode() + { + return x.hashCode() ^ y.hashCode(); + } + } +}