259 lines
8.1 KiB
Java
259 lines
8.1 KiB
Java
/**
|
|
* Copyright (c) 2011-2017, SpaceToad and the BuildCraft Team
|
|
* http://www.mod-buildcraft.com
|
|
* <p/>
|
|
* BuildCraft is distributed under the terms of the Minecraft Mod Public
|
|
* License 1.0, or MMPL. Please check the contents of the license located in
|
|
* http://www.mod-buildcraft.com/MMPL-1.0.txt
|
|
*/
|
|
package buildcraft.transport.render;
|
|
|
|
import buildcraft.BuildCraftCore;
|
|
import buildcraft.core.render.BCSimpleBlockRenderingHandler;
|
|
import net.minecraft.block.Block;
|
|
import net.minecraft.block.BlockChest;
|
|
import net.minecraft.client.Minecraft;
|
|
import net.minecraft.client.renderer.RenderBlocks;
|
|
import net.minecraft.client.renderer.Tessellator;
|
|
import net.minecraft.tileentity.TileEntity;
|
|
import net.minecraft.world.IBlockAccess;
|
|
|
|
import cpw.mods.fml.client.registry.ISimpleBlockRenderingHandler;
|
|
import net.minecraftforge.common.util.ForgeDirection;
|
|
|
|
import buildcraft.api.core.IIconProvider;
|
|
import buildcraft.api.transport.pluggable.IPipePluggableRenderer;
|
|
import buildcraft.api.transport.pluggable.PipePluggable;
|
|
import buildcraft.core.CoreConstants;
|
|
import buildcraft.core.lib.render.FakeBlock;
|
|
import buildcraft.core.lib.utils.ColorUtils;
|
|
import buildcraft.transport.BlockGenericPipe;
|
|
import buildcraft.transport.PipeIconProvider;
|
|
import buildcraft.transport.PipeRenderState;
|
|
import buildcraft.transport.TileGenericPipe;
|
|
import buildcraft.transport.TransportProxy;
|
|
import buildcraft.transport.pipes.PipeStructureCobblestone;
|
|
|
|
public class PipeRendererWorld extends BCSimpleBlockRenderingHandler {
|
|
|
|
public static int renderPass = -1;
|
|
public static float zFightOffset = 1F / 4096F;
|
|
private static final double[] CHEST_BB = new double[]{
|
|
0, 0.0625F, 0.0625F,
|
|
0.875F, 0.9375F, 0.9375F
|
|
};
|
|
|
|
public boolean renderPipe(RenderBlocks renderblocks, IBlockAccess iblockaccess, TileGenericPipe tile, int x, int y, int z) {
|
|
PipeRenderState state = tile.renderState;
|
|
IIconProvider icons = tile.getPipeIcons();
|
|
FakeBlock fakeBlock = FakeBlock.INSTANCE;
|
|
int glassColor = tile.getPipeColor();
|
|
|
|
if (icons == null) {
|
|
return false;
|
|
}
|
|
|
|
boolean rendered = false; // Set to true if you're *certain* the pass rendered something.
|
|
|
|
if (renderPass == 0 || glassColor >= 0) {
|
|
// Pass 0 handles the pipe texture, pass 1 handles the transparent stained glass
|
|
int connectivity = state.pipeConnectionMatrix.getMask();
|
|
float[] dim = new float[6];
|
|
|
|
if (renderPass == 1) {
|
|
fakeBlock.setColor(ColorUtils.getRGBColor(glassColor));
|
|
} else if (glassColor >= 0 && tile.getPipe() instanceof PipeStructureCobblestone) {
|
|
if (glassColor == 0) {
|
|
fakeBlock.setColor(0xDFDFDF);
|
|
} else {
|
|
fakeBlock.setColor(ColorUtils.getRGBColor(glassColor));
|
|
}
|
|
}
|
|
|
|
// render the unconnected pipe faces of the center block (if any)
|
|
|
|
if (connectivity != 0x3f) { // note: 0x3f = 0x111111 = all sides
|
|
resetToCenterDimensions(dim);
|
|
|
|
if (renderPass == 0) {
|
|
fakeBlock.getTextureState().set(icons.getIcon(state.textureMatrix.getTextureIndex(ForgeDirection.UNKNOWN)));
|
|
} else {
|
|
fakeBlock.getTextureState().set(PipeIconProvider.TYPE.PipeStainedOverlay.getIcon());
|
|
}
|
|
|
|
fixForRenderPass(dim);
|
|
|
|
renderTwoWayBlock(renderblocks, fakeBlock, x, y, z, dim, connectivity ^ 0x3f);
|
|
rendered = true;
|
|
}
|
|
|
|
// render the connecting pipe faces
|
|
for (int dir = 0; dir < 6; dir++) {
|
|
int mask = 1 << dir;
|
|
|
|
if ((connectivity & mask) == 0) {
|
|
continue; // no connection towards dir
|
|
}
|
|
|
|
// center piece offsets
|
|
resetToCenterDimensions(dim);
|
|
|
|
// extend block towards dir as it's connected to there
|
|
dim[dir / 2] = dir % 2 == 0 ? 0 : CoreConstants.PIPE_MAX_POS;
|
|
dim[dir / 2 + 3] = dir % 2 == 0 ? CoreConstants.PIPE_MIN_POS : 1;
|
|
|
|
// the mask points to all faces perpendicular to dir, i.e. dirs 0+1 -> mask 111100, 1+2 -> 110011, 3+5 -> 001111
|
|
int renderMask = (3 << (dir & 0x6)) ^ 0x3f;
|
|
|
|
fixForRenderPass(dim);
|
|
|
|
// render sub block
|
|
if (renderPass == 0) {
|
|
fakeBlock.getTextureState().set(icons.getIcon(state.textureMatrix.getTextureIndex(ForgeDirection.VALID_DIRECTIONS[dir])));
|
|
} else {
|
|
fakeBlock.getTextureState().set(PipeIconProvider.TYPE.PipeStainedOverlay.getIcon());
|
|
}
|
|
|
|
renderTwoWayBlock(renderblocks, fakeBlock, x, y, z, dim, renderMask);
|
|
rendered = true;
|
|
|
|
// Render connection to block
|
|
if (Minecraft.getMinecraft().gameSettings.fancyGraphics) {
|
|
ForgeDirection side = ForgeDirection.getOrientation(dir);
|
|
int px = x + side.offsetX;
|
|
int py = y + side.offsetY;
|
|
int pz = z + side.offsetZ;
|
|
Block block = iblockaccess.getBlock(px, py, pz);
|
|
if (!(block instanceof BlockGenericPipe) && !block.isOpaqueCube()) {
|
|
|
|
double[] blockBB;
|
|
if (block instanceof BlockChest) {
|
|
// work around what seems to be a vanilla bug?
|
|
blockBB = CHEST_BB;
|
|
} else {
|
|
block.setBlockBoundsBasedOnState(iblockaccess, px, py, pz);
|
|
|
|
blockBB = new double[]{
|
|
block.getBlockBoundsMinY(),
|
|
block.getBlockBoundsMinX(),
|
|
block.getBlockBoundsMinZ(),
|
|
block.getBlockBoundsMaxY(),
|
|
block.getBlockBoundsMaxX(),
|
|
block.getBlockBoundsMaxZ()
|
|
};
|
|
}
|
|
|
|
if ((dir % 2 == 1 && blockBB[dir / 2] != 0) || (dir % 2 == 0 && blockBB[dir / 2 + 3] != 1)) {
|
|
resetToCenterDimensions(dim);
|
|
|
|
if (dir % 2 == 1) {
|
|
dim[dir / 2] = 0;
|
|
dim[dir / 2 + 3] = (float) blockBB[dir / 2];
|
|
} else {
|
|
dim[dir / 2] = (float) blockBB[dir / 2 + 3];
|
|
dim[dir / 2 + 3] = 1;
|
|
}
|
|
|
|
fixForRenderPass(dim);
|
|
|
|
renderTwoWayBlock(renderblocks, fakeBlock, x + side.offsetX,
|
|
y + side.offsetY,
|
|
z + side.offsetZ, dim, renderMask);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
fakeBlock.setColor(0xFFFFFF);
|
|
}
|
|
|
|
renderblocks.setRenderBounds(0.0F, 0.0F, 0.0F, 1.0F, 1.0F, 1.0F);
|
|
|
|
for (ForgeDirection dir : ForgeDirection.VALID_DIRECTIONS) {
|
|
if (tile.hasPipePluggable(dir)) {
|
|
PipePluggable p = tile.getPipePluggable(dir);
|
|
IPipePluggableRenderer r = p.getRenderer();
|
|
if (r != null) {
|
|
r.renderPluggable(renderblocks, tile.getPipe(), dir, p, fakeBlock, renderPass, x, y, z);
|
|
}
|
|
}
|
|
}
|
|
|
|
return rendered;
|
|
}
|
|
|
|
private void fixForRenderPass(float[] dim) {
|
|
if (renderPass == 1) {
|
|
for (int i = 0; i < 3; i++) {
|
|
dim[i] += zFightOffset;
|
|
}
|
|
|
|
for (int i = 3; i < 6; i++) {
|
|
dim[i] -= zFightOffset;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void resetToCenterDimensions(float[] dim) {
|
|
for (int i = 0; i < 3; i++) {
|
|
dim[i] = CoreConstants.PIPE_MIN_POS;
|
|
dim[i + 3] = CoreConstants.PIPE_MAX_POS;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Render a block with normal and inverted vertex order so back face culling
|
|
* doesn't have any effect.
|
|
*/
|
|
private void renderTwoWayBlock(RenderBlocks renderblocks, FakeBlock stateHost, int x, int y, int z, float[] dim, int mask) {
|
|
assert mask != 0;
|
|
|
|
int c = stateHost.getBlockColor();
|
|
float r = ((c & 0xFF0000) >> 16) / 255.0f;
|
|
float g = ((c & 0x00FF00) >> 8) / 255.0f;
|
|
float b = (c & 0x0000FF) / 255.0f;
|
|
|
|
stateHost.setRenderMask(mask);
|
|
renderblocks.setRenderBounds(dim[2], dim[0], dim[1], dim[5], dim[3], dim[4]);
|
|
renderblocks.renderStandardBlockWithColorMultiplier(stateHost, x, y, z, r, g, b);
|
|
|
|
stateHost.setRenderMask((mask & 0x15) << 1 | (mask & 0x2a) >> 1); // pairwise swapped mask
|
|
renderblocks.setRenderBounds(dim[5], dim[3], dim[4], dim[2], dim[0], dim[1]);
|
|
renderblocks.renderStandardBlockWithColorMultiplier(stateHost, x, y, z, r * 0.67f, g * 0.67f, b * 0.67f);
|
|
|
|
stateHost.setRenderAllSides();
|
|
}
|
|
|
|
@Override
|
|
public void renderInventoryBlock(Block block, int metadata, int modelID, RenderBlocks renderer) {
|
|
// Done with a special item renderer
|
|
}
|
|
|
|
@Override
|
|
public boolean renderWorldBlock(IBlockAccess world, int x, int y, int z, Block block, int modelId, RenderBlocks renderer) {
|
|
boolean rendered = false;
|
|
TileEntity tile = world.getTileEntity(x, y, z);
|
|
|
|
if (tile instanceof TileGenericPipe) {
|
|
TileGenericPipe pipeTile = (TileGenericPipe) tile;
|
|
rendered = renderPipe(renderer, world, pipeTile, x, y, z);
|
|
}
|
|
|
|
if (!rendered) {
|
|
fixEmptyAlphaPass(x, y, z);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldRender3DInInventory(int modelId) {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public int getRenderId() {
|
|
return TransportProxy.pipeModel;
|
|
}
|
|
}
|