ForgePatch/common/net/minecraftforge/fluids/RenderBlockFluid.java
2013-08-03 23:20:34 +02:00

327 lines
No EOL
13 KiB
Java

package net.minecraftforge.fluids;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.Icon;
import net.minecraft.util.MathHelper;
import net.minecraft.world.IBlockAccess;
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
/**
* Default renderer for Forge fluid blocks.
*
* @author King Lemming
*
*/
public class RenderBlockFluid implements ISimpleBlockRenderingHandler
{
public static RenderBlockFluid instance = new RenderBlockFluid();
static final float LIGHT_Y_NEG = 0.5F;
static final float LIGHT_Y_POS = 1.0F;
static final float LIGHT_XZ_NEG = 0.8F;
static final float LIGHT_XZ_POS = 0.6F;
static final double RENDER_OFFSET = 0.0010000000474974513D;
public float getFluidHeightAverage(float[] flow)
{
float total = 0;
int count = 0;
float end = 0;
for (int i = 0; i < flow.length; i++)
{
if (flow[i] >= 0.875F && end != 1F)
{
end = flow[i];
}
if (flow[i] >= 0)
{
total += flow[i];
count++;
}
}
if (end == 0)
end = total / count;
return end;
}
public float getFluidHeightForRender(IBlockAccess world, int x, int y, int z, BlockFluidBase block)
{
if (world.getBlockId(x, y, z) == block.blockID)
{
if (world.getBlockMaterial(x, y - block.densityDir, z).isLiquid())
{
return 1;
}
if (world.getBlockMetadata(x, y, z) == block.getMaxRenderHeightMeta())
{
return 0.875F;
}
}
return !world.getBlockMaterial(x, y, z).isSolid() && world.getBlockId(x, y - block.densityDir, z) == block.blockID ? 1 : block.getQuantaPercentage(world, x, y, z) * 0.875F;
}
/* ISimpleBlockRenderingHandler */
@Override
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer){}
@Override
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer)
{
if (!(block instanceof BlockFluidBase))
{
return false;
}
Tessellator tessellator = Tessellator.instance;
int color = block.colorMultiplier(world, x, y, z);
float red = (color >> 16 & 255) / 255.0F;
float green = (color >> 8 & 255) / 255.0F;
float blue = (color & 255) / 255.0F;
BlockFluidBase theFluid = (BlockFluidBase) block;
int bMeta = world.getBlockMetadata(x, y, z);
boolean renderTop = world.getBlockId(x, y - theFluid.densityDir, z) != theFluid.blockID;
boolean renderBottom = block.shouldSideBeRendered(world, x, y + theFluid.densityDir, z, 0) && world.getBlockId(x, y + theFluid.densityDir, z) != theFluid.blockID;
boolean[] renderSides = new boolean[]
{
block.shouldSideBeRendered(world, x, y, z - 1, 2),
block.shouldSideBeRendered(world, x, y, z + 1, 3),
block.shouldSideBeRendered(world, x - 1, y, z, 4),
block.shouldSideBeRendered(world, x + 1, y, z, 5)
};
if (!renderTop && !renderBottom && !renderSides[0] && !renderSides[1] && !renderSides[2] && !renderSides[3])
{
return false;
}
else
{
boolean rendered = false;
double heightNW, heightSW, heightSE, heightNE;
float flow11 = getFluidHeightForRender(world, x, y, z, theFluid);
if (flow11 != 1)
{
float flow00 = getFluidHeightForRender(world, x - 1, y, z - 1, theFluid);
float flow01 = getFluidHeightForRender(world, x - 1, y, z, theFluid);
float flow02 = getFluidHeightForRender(world, x - 1, y, z + 1, theFluid);
float flow10 = getFluidHeightForRender(world, x, y, z - 1, theFluid);
float flow12 = getFluidHeightForRender(world, x, y, z + 1, theFluid);
float flow20 = getFluidHeightForRender(world, x + 1, y, z - 1, theFluid);
float flow21 = getFluidHeightForRender(world, x + 1, y, z, theFluid);
float flow22 = getFluidHeightForRender(world, x + 1, y, z + 1, theFluid);
heightNW = getFluidHeightAverage(new float[]{ flow00, flow01, flow10, flow11 });
heightSW = getFluidHeightAverage(new float[]{ flow01, flow02, flow12, flow11 });
heightSE = getFluidHeightAverage(new float[]{ flow12, flow21, flow22, flow11 });
heightNE = getFluidHeightAverage(new float[]{ flow10, flow20, flow21, flow11 });
}
else
{
heightNW = flow11;
heightSW = flow11;
heightSE = flow11;
heightNE = flow11;
}
boolean rises = theFluid.densityDir == 1;
if (renderer.renderAllFaces || renderTop)
{
rendered = true;
Icon iconStill = block.getIcon(1, bMeta);
float flowDir = (float) BlockFluidBase.getFlowDirection(world, x, y, z);
if (flowDir > -999.0F)
{
iconStill = block.getIcon(2, bMeta);
}
heightNW -= RENDER_OFFSET;
heightSW -= RENDER_OFFSET;
heightSE -= RENDER_OFFSET;
heightNE -= RENDER_OFFSET;
double u1, u2, u3, u4, v1, v2, v3, v4;
if (flowDir < -999.0F)
{
u2 = iconStill.getInterpolatedU(0.0D);
v2 = iconStill.getInterpolatedV(0.0D);
u1 = u2;
v1 = iconStill.getInterpolatedV(16.0D);
u4 = iconStill.getInterpolatedU(16.0D);
v4 = v1;
u3 = u4;
v3 = v2;
}
else
{
float xFlow = MathHelper.sin(flowDir) * 0.25F;
float zFlow = MathHelper.cos(flowDir) * 0.25F;
u2 = iconStill.getInterpolatedU(8.0F + (-zFlow - xFlow) * 16.0F);
v2 = iconStill.getInterpolatedV(8.0F + (-zFlow + xFlow) * 16.0F);
u1 = iconStill.getInterpolatedU(8.0F + (-zFlow + xFlow) * 16.0F);
v1 = iconStill.getInterpolatedV(8.0F + (zFlow + xFlow) * 16.0F);
u4 = iconStill.getInterpolatedU(8.0F + (zFlow + xFlow) * 16.0F);
v4 = iconStill.getInterpolatedV(8.0F + (zFlow - xFlow) * 16.0F);
u3 = iconStill.getInterpolatedU(8.0F + (zFlow - xFlow) * 16.0F);
v3 = iconStill.getInterpolatedV(8.0F + (-zFlow - xFlow) * 16.0F);
}
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y, z));
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
if (!rises)
{
tessellator.addVertexWithUV(x + 0, y + heightNW, z + 0, u2, v2);
tessellator.addVertexWithUV(x + 0, y + heightSW, z + 1, u1, v1);
tessellator.addVertexWithUV(x + 1, y + heightSE, z + 1, u4, v4);
tessellator.addVertexWithUV(x + 1, y + heightNE, z + 0, u3, v3);
}
else
{
tessellator.addVertexWithUV(x + 1, y + 1 - heightNE, z + 0, u3, v3);
tessellator.addVertexWithUV(x + 1, y + 1 - heightSE, z + 1, u4, v4);
tessellator.addVertexWithUV(x + 0, y + 1 - heightSW, z + 1, u1, v1);
tessellator.addVertexWithUV(x + 0, y + 1 - heightNW, z + 0, u2, v2);
}
}
if (renderer.renderAllFaces || renderBottom)
{
rendered = true;
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x, y - 1, z));
if (!rises)
{
tessellator.setColorOpaque_F(LIGHT_Y_NEG * red, LIGHT_Y_NEG * green, LIGHT_Y_NEG * blue);
renderer.renderFaceYNeg(block, x, y + RENDER_OFFSET, z, block.getIcon(0, bMeta));
}
else
{
tessellator.setColorOpaque_F(LIGHT_Y_POS * red, LIGHT_Y_POS * green, LIGHT_Y_POS * blue);
renderer.renderFaceYPos(block, x, y + RENDER_OFFSET, z, block.getIcon(1, bMeta));
}
}
for (int side = 0; side < 4; ++side)
{
int x2 = x;
int z2 = z;
switch (side)
{
case 0: --z2; break;
case 1: ++z2; break;
case 2: --x2; break;
case 3: ++x2; break;
}
Icon iconFlow = block.getIcon(side + 2, bMeta);
if (renderer.renderAllFaces || renderSides[side])
{
rendered = true;
double ty1;
double tx1;
double ty2;
double tx2;
double tz1;
double tz2;
if (side == 0)
{
ty1 = heightNW;
ty2 = heightNE;
tx1 = x;
tx2 = x + 1;
tz1 = z + RENDER_OFFSET;
tz2 = z + RENDER_OFFSET;
}
else if (side == 1)
{
ty1 = heightSE;
ty2 = heightSW;
tx1 = x + 1;
tx2 = x;
tz1 = z + 1 - RENDER_OFFSET;
tz2 = z + 1 - RENDER_OFFSET;
}
else if (side == 2)
{
ty1 = heightSW;
ty2 = heightNW;
tx1 = x + RENDER_OFFSET;
tx2 = x + RENDER_OFFSET;
tz1 = z + 1;
tz2 = z;
}
else
{
ty1 = heightNE;
ty2 = heightSE;
tx1 = x + 1 - RENDER_OFFSET;
tx2 = x + 1 - RENDER_OFFSET;
tz1 = z;
tz2 = z + 1;
}
float u1Flow = iconFlow.getInterpolatedU(0.0D);
float u2Flow = iconFlow.getInterpolatedU(8.0D);
float v1Flow = iconFlow.getInterpolatedV((1.0D - ty1) * 16.0D * 0.5D);
float v2Flow = iconFlow.getInterpolatedV((1.0D - ty2) * 16.0D * 0.5D);
float v3Flow = iconFlow.getInterpolatedV(8.0D);
tessellator.setBrightness(block.getMixedBrightnessForBlock(world, x2, y, z2));
float sideLighting = 1.0F;
if (side < 2)
{
sideLighting = LIGHT_XZ_NEG;
}
else
{
sideLighting = LIGHT_XZ_POS;
}
tessellator.setColorOpaque_F(LIGHT_Y_POS * sideLighting * red, LIGHT_Y_POS * sideLighting * green, LIGHT_Y_POS * sideLighting * blue);
if (!rises)
{
tessellator.addVertexWithUV(tx1, y + ty1, tz1, u1Flow, v1Flow);
tessellator.addVertexWithUV(tx2, y + ty2, tz2, u2Flow, v2Flow);
tessellator.addVertexWithUV(tx2, y + 0, tz2, u2Flow, v3Flow);
tessellator.addVertexWithUV(tx1, y + 0, tz1, u1Flow, v3Flow);
}
else
{
tessellator.addVertexWithUV(tx1, y + 1 - 0, tz1, u1Flow, v3Flow);
tessellator.addVertexWithUV(tx2, y + 1 - 0, tz2, u2Flow, v3Flow);
tessellator.addVertexWithUV(tx2, y + 1 - ty2, tz2, u2Flow, v2Flow);
tessellator.addVertexWithUV(tx1, y + 1 - ty1, tz1, u1Flow, v1Flow);
}
}
}
renderer.renderMinY = 0;
renderer.renderMaxY = 1;
return rendered;
}
}
@Override
public boolean shouldRender3DInInventory(){ return false; }
@Override
public int getRenderId()
{
return FluidRegistry.renderIdFluid;
}
}