package mekanism.client.render.transmitter;
import java.util.HashMap;
import mekanism.api.MekanismConfig.client;
import mekanism.client.render.MekanismRenderer;
import mekanism.client.render.MekanismRenderer.DisplayInteger;
import mekanism.client.render.MekanismRenderer.FluidType;
import mekanism.client.render.MekanismRenderer.Model3D;
import mekanism.common.ColourRGBA;
import mekanism.common.multipart.PartMechanicalPipe;
import mekanism.common.multipart.PartSidedPipe.ConnectionType;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.client.renderer.VertexBuffer;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.init.Blocks;
import net.minecraft.util.EnumFacing;
import net.minecraftforge.fluids.Fluid;
import org.lwjgl.opengl.GL11;
public class RenderMechanicalPipe extends RenderTransmitterBase<PartMechanicalPipe>
{
private static HashMap<Integer, HashMap<Fluid, DisplayInteger[]>> cachedLiquids = new HashMap<Integer, HashMap<Fluid, DisplayInteger[]>>();
private static final int stages = 100;
private static final double height = 0.45;
private static final double offset = 0.015;
public RenderMechanicalPipe()
{
super();
}
@Override
public void renderMultipartAt(PartMechanicalPipe pipe, double x, double y, double z, float partialTick, int destroyStage)
{
if(client.opaqueTransmitters)
{
return;
}
float targetScale;
if(pipe.getTransmitter().hasTransmitterNetwork())
{
targetScale = pipe.getTransmitter().getTransmitterNetwork().fluidScale;
}
else {
targetScale = (float)pipe.buffer.getFluidAmount() / (float)pipe.buffer.getCapacity();
}
if(Math.abs(pipe.currentScale - targetScale) > 0.01)
{
pipe.currentScale = (12 * pipe.currentScale + targetScale) / 13;
}
else {
pipe.currentScale = targetScale;
}
Fluid fluid;
if(pipe.getTransmitter().hasTransmitterNetwork())
{
fluid = pipe.getTransmitter().getTransmitterNetwork().refFluid;
}
else {
fluid = pipe.getBuffer() == null ? null : pipe.getBuffer().getFluid();
}
float scale = Math.min(pipe.currentScale, 1);
if(scale > 0.01 && fluid != null)
{
push();
MekanismRenderer.glowOn(fluid.getLuminosity());
MekanismRenderer.colorFluid(fluid);
bindTexture(MekanismRenderer.getBlocksTexture());
GL11.glTranslated(x, y, z);
boolean gas = fluid.isGaseous();
for(EnumFacing side : EnumFacing.VALUES)
{
if(pipe.getConnectionType(side) == ConnectionType.NORMAL)
{
DisplayInteger[] displayLists = getListAndRender(side, fluid);
if(displayLists != null)
{
if(!gas)
{
displayLists[Math.max(3, (int)((float)scale*(stages-1)))].render();
}
else {
GL11.glColor4f(1F, 1F, 1F, scale);
displayLists[stages-1].render();
}
}
}
else if(pipe.getConnectionType(side) != ConnectionType.NONE)
{
GL11.glTranslated(0.5, 0.5, 0.5);
Tessellator tessellator = Tessellator.getInstance();
VertexBuffer worldRenderer = tessellator.getBuffer();
if(renderFluidInOut(worldRenderer, side, pipe))
{
tessellator.draw();
}
GL11.glTranslated(-0.5, -0.5, -0.5);
}
}
DisplayInteger[] displayLists = getListAndRender(null, fluid);
if(displayLists != null)
{
if(!gas)
{
displayLists[Math.max(3, (int)((float)scale*(stages-1)))].render();
}
else {
GL11.glColor4f(1F, 1F, 1F, scale);
displayLists[stages-1].render();
}
}
MekanismRenderer.glowOff();
MekanismRenderer.resetColor();
pop();
}
}
private DisplayInteger[] getListAndRender(EnumFacing side, Fluid fluid)
{
if(fluid == null)
{
return null;
}
int sideOrdinal = side != null ? side.ordinal() : 6;
if(cachedLiquids.containsKey(sideOrdinal) && cachedLiquids.get(sideOrdinal).containsKey(fluid))
{
return cachedLiquids.get(sideOrdinal).get(fluid);
}
Model3D toReturn = new Model3D();
toReturn.baseBlock = Blocks.WATER;
toReturn.setTexture(MekanismRenderer.getFluidTexture(fluid, FluidType.STILL));
if(side != null)
{
toReturn.setSideRender(side, false);
toReturn.setSideRender(side.getOpposite(), false);
}
DisplayInteger[] displays = new DisplayInteger[stages];
if(cachedLiquids.containsKey(sideOrdinal))
{
cachedLiquids.get(sideOrdinal).put(fluid, displays);
}
else {
HashMap<Fluid, DisplayInteger[]> map = new HashMap<Fluid, DisplayInteger[]>();
map.put(fluid, displays);
cachedLiquids.put(sideOrdinal, map);
}
for(int i = 0; i < stages; i++)
{
displays[i] = DisplayInteger.createAndStart();
switch(sideOrdinal)
{
case 6:
{
toReturn.minX = 0.25 + offset;
toReturn.minY = 0.25 + offset;
toReturn.minZ = 0.25 + offset;
toReturn.maxX = 0.75 - offset;
toReturn.maxY = 0.25 + offset + ((float)i / (float)stages)*height;
toReturn.maxZ = 0.75 - offset;
break;
}
case 0:
{
toReturn.minX = 0.5 - (((float)i / (float)stages)*height)/2;
toReturn.minY = 0.0;
toReturn.minZ = 0.5 - (((float)i / (float)stages)*height)/2;
toReturn.maxX = 0.5 + (((float)i / (float)stages)*height)/2;
toReturn.maxY = 0.25 + offset;
toReturn.maxZ = 0.5 + (((float)i / (float)stages)*height)/2;
break;
}
case 1:
{
toReturn.minX = 0.5 - (((float)i / (float)stages)*height)/2;
toReturn.minY = 0.25 - offset + ((float)i / (float)stages)*height;
toReturn.minZ = 0.5 - (((float)i / (float)stages)*height)/2;
toReturn.maxX = 0.5 + (((float)i / (float)stages)*height)/2;
toReturn.maxY = 1.0;
toReturn.maxZ = 0.5 + (((float)i / (float)stages)*height)/2;
break;
}
case 2:
{
toReturn.minX = 0.25 + offset;
toReturn.minY = 0.25 + offset;
toReturn.minZ = 0.0;
toReturn.maxX = 0.75 - offset;
toReturn.maxY = 0.25 + offset + ((float)i / (float)stages)*height;
toReturn.maxZ = 0.25 + offset;
break;
}
case 3:
{
toReturn.minX = 0.25 + offset;
toReturn.minY = 0.25 + offset;
toReturn.minZ = 0.75 - offset;
toReturn.maxX = 0.75 - offset;
toReturn.maxY = 0.25 + offset + ((float)i / (float)stages)*height;
toReturn.maxZ = 1.0;
break;
}
case 4:
{
toReturn.minX = 0.0;
toReturn.minY = 0.25 + offset;
toReturn.minZ = 0.25 + offset;
toReturn.maxX = 0.25 + offset;
toReturn.maxY = 0.25 + offset + ((float)i / (float)stages)*height;
toReturn.maxZ = 0.75 - offset;
break;
}
case 5:
{
toReturn.minX = 0.75 - offset;
toReturn.minY = 0.25 + offset;
toReturn.minZ = 0.25 + offset;
toReturn.maxX = 1.0;
toReturn.maxY = 0.25 + offset + ((float)i / (float)stages)*height;
toReturn.maxZ = 0.75 - offset;
break;
}
}
MekanismRenderer.renderObject(toReturn);
displays[i].endList();
}
return displays;
}
public boolean renderFluidInOut(VertexBuffer renderer, EnumFacing side, PartMechanicalPipe pipe)
{
if(pipe != null && pipe.getTransmitter() != null && pipe.getTransmitter().getTransmitterNetwork() != null)
{
bindTexture(MekanismRenderer.getBlocksTexture());
TextureAtlasSprite tex = MekanismRenderer.getFluidTexture(pipe.getTransmitter().getTransmitterNetwork().refFluid, FluidType.STILL);
renderTransparency(renderer, tex, getModelForSide(pipe, side), new ColourRGBA(1.0, 1.0, 1.0, pipe.currentScale));
return true;
}
return false;
}
public static void onStitch()
{
cachedLiquids.clear();
}
}