Applied-Energistics-2-tiler.../client/render/BusRenderHelper.java
AlgorithmX2 3080510317 Major Update for Cable Rendering.
TESRs will are no longer used if the tile contains no dynamic renders.
Added alpha pass rendering for stained glass.
Enabled Stained Glass facades.
Cables / Facades have less geometry by hiding faces on connected boxes.
Added AlphaPass Option to disable AlphaPass Cables rendering ( fixes crash with Immbis Microblocks. )
2014-05-04 19:51:05 -05:00

429 lines
10 KiB
Java

package appeng.client.render;
import java.util.EnumSet;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.IIcon;
import net.minecraftforge.common.util.ForgeDirection;
import appeng.api.AEApi;
import appeng.api.parts.IPart;
import appeng.api.parts.IPartCollsionHelper;
import appeng.api.parts.IPartRenderHelper;
import appeng.api.parts.ISimplifiedBundle;
import appeng.block.AEBaseBlock;
import appeng.core.AEConfig;
import appeng.core.features.AEFeature;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class BusRenderHelper implements IPartRenderHelper
{
final public static BusRenderHelper instance = new BusRenderHelper();
double minX = 0;
double minY = 0;
double minZ = 0;
double maxX = 16;
double maxY = 16;
double maxZ = 16;
AEBaseBlock blk = (AEBaseBlock) AEApi.instance().blocks().blockMultiPart.block();
BaseBlockRender bbr = new BaseBlockRender();
public ForgeDirection ax;
public ForgeDirection ay;
public ForgeDirection az;
int color = 0xffffff;
class BoundBoxCalculator implements IPartCollsionHelper
{
public boolean started = false;
float minX;
float minY;
float minZ;
float maxX;
float maxY;
float maxZ;
@Override
public void addBox(double minX, double minY, double minZ, double maxX, double maxY, double maxZ)
{
if ( started )
{
this.minX = Math.min( this.minX, (float) minX );
this.minY = Math.min( this.minY, (float) minY );
this.minZ = Math.min( this.minZ, (float) minZ );
this.maxX = Math.max( this.maxX, (float) maxX );
this.maxY = Math.max( this.maxY, (float) maxY );
this.maxZ = Math.max( this.maxZ, (float) maxZ );
}
else
{
started = true;
this.minX = (float) minX;
this.minY = (float) minY;
this.minZ = (float) minZ;
this.maxX = (float) maxX;
this.maxY = (float) maxY;
this.maxZ = (float) maxZ;
}
}
@Override
public ForgeDirection getWorldX()
{
return ax;
}
@Override
public ForgeDirection getWorldY()
{
return ay;
}
@Override
public ForgeDirection getWorldZ()
{
return az;
}
@Override
public boolean isBBCollision()
{
return false;
}
};
BoundBoxCalculator bbc = new BoundBoxCalculator();
int renderingForPass = 0;
int currentPass = 0;
int itemsRendered = 0;
boolean noAlphaPass = AEConfig.instance.isFeatureEnabled( AEFeature.AlphaPass ) == false;
public int getItemsRendered()
{
return itemsRendered;
}
public void setPass(int pass)
{
renderingForPass = 0;
currentPass = pass;
itemsRendered = 0;
}
@Override
public void renderForPass(int pass)
{
renderingForPass = pass;
}
public boolean renderThis()
{
if ( renderingForPass == currentPass || noAlphaPass )
{
itemsRendered++;
return true;
}
return false;
}
@Override
public void normalRendering()
{
RenderBlocksWorkaround rbw = BusRenderer.instance.renderer;
rbw.calculations = true;
rbw.useTextures = true;
rbw.enableAO = false;
}
@Override
public ISimplifiedBundle useSimpliedRendering(int x, int y, int z, IPart p, ISimplifiedBundle sim)
{
RenderBlocksWorkaround rbw = BusRenderer.instance.renderer;
if ( sim != null && rbw.similarLighting( blk, rbw.blockAccess, x, y, z, sim ) )
{
rbw.populate( sim );
rbw.faces = EnumSet.allOf( ForgeDirection.class );
rbw.calculations = false;
rbw.useTextures = false;
return sim;
}
else
{
rbw.calculations = true;
rbw.faces.clear();
bbc.started = false;
p.getBoxes( bbc );
if ( bbc.minX < 1 )
bbc.minX = 1;
if ( bbc.minY < 1 )
bbc.minY = 1;
if ( bbc.minZ < 1 )
bbc.minZ = 1;
if ( bbc.maxX > 15 )
bbc.maxX = 15;
if ( bbc.maxY > 15 )
bbc.maxY = 15;
if ( bbc.maxZ > 15 )
bbc.maxZ = 15;
setBounds( bbc.minX, bbc.minY, bbc.minZ, bbc.maxX, bbc.maxY, bbc.maxZ );
bbr.renderBlockBounds( rbw, minX, minY, minZ, maxX, maxY, maxZ, ax, ay, az );
rbw.renderStandardBlock( blk, x, y, z );
rbw.faces = EnumSet.allOf( ForgeDirection.class );
rbw.calculations = false;
rbw.useTextures = false;
return rbw.getLightingCache();
}
}
@Override
public void setBounds(float minx, float miny, float minz, float maxx, float maxy, float maxz)
{
minX = minx;
minY = miny;
minZ = minz;
maxX = maxx;
maxY = maxy;
maxZ = maxz;
}
@Override
public void setInvColor(int newColor)
{
color = newColor;
}
@Override
public void setTexture(IIcon ico)
{
blk.getRendererInstance().setTemporaryRenderIcon( ico );
}
@Override
public void setTexture(IIcon Down, IIcon Up, IIcon North, IIcon South, IIcon West, IIcon East)
{
IIcon list[] = new IIcon[6];
list[0] = Down;
list[1] = Up;
list[2] = North;
list[3] = South;
list[4] = West;
list[5] = East;
blk.getRendererInstance().setTemporaryRenderIcons( list[mapRotation( ForgeDirection.UP ).ordinal()],
list[mapRotation( ForgeDirection.DOWN ).ordinal()], list[mapRotation( ForgeDirection.SOUTH ).ordinal()],
list[mapRotation( ForgeDirection.NORTH ).ordinal()], list[mapRotation( ForgeDirection.EAST ).ordinal()],
list[mapRotation( ForgeDirection.WEST ).ordinal()] );
}
public ForgeDirection mapRotation(ForgeDirection dir)
{
ForgeDirection forward = az;
ForgeDirection up = ay;
ForgeDirection west = ForgeDirection.UNKNOWN;
if ( forward == null || up == null )
return dir;
int west_x = forward.offsetY * up.offsetZ - forward.offsetZ * up.offsetY;
int west_y = forward.offsetZ * up.offsetX - forward.offsetX * up.offsetZ;
int west_z = forward.offsetX * up.offsetY - forward.offsetY * up.offsetX;
for (ForgeDirection dx : ForgeDirection.VALID_DIRECTIONS)
if ( dx.offsetX == west_x && dx.offsetY == west_y && dx.offsetZ == west_z )
west = dx;
if ( dir.equals( forward ) )
return ForgeDirection.SOUTH;
if ( dir.equals( forward.getOpposite() ) )
return ForgeDirection.NORTH;
if ( dir.equals( up ) )
return ForgeDirection.UP;
if ( dir.equals( up.getOpposite() ) )
return ForgeDirection.DOWN;
if ( dir.equals( west ) )
return ForgeDirection.WEST;
if ( dir.equals( west.getOpposite() ) )
return ForgeDirection.EAST;
return ForgeDirection.UNKNOWN;
}
@Override
public void renderInventoryBox(RenderBlocks renderer)
{
renderer.setRenderBounds( minX / 16.0, minY / 16.0, minZ / 16.0, maxX / 16.0, maxY / 16.0, maxZ / 16.0 );
bbr.renderInvBlock( EnumSet.allOf( ForgeDirection.class ), blk, null, Tessellator.instance, color, renderer );
}
@Override
public void renderInventoryFace(IIcon IIcon, ForgeDirection face, RenderBlocks renderer)
{
renderer.setRenderBounds( minX / 16.0, minY / 16.0, minZ / 16.0, maxX / 16.0, maxY / 16.0, maxZ / 16.0 );
setTexture( IIcon );
bbr.renderInvBlock( EnumSet.of( face ), blk, null, Tessellator.instance, color, renderer );
}
@Override
public void renderBlock(int x, int y, int z, RenderBlocks renderer)
{
if ( !renderThis() )
return;
AEBaseBlock blk = (AEBaseBlock) AEApi.instance().blocks().blockMultiPart.block();
BlockRenderInfo info = blk.getRendererInstance();
ForgeDirection forward = BusRenderHelper.instance.az;
ForgeDirection up = BusRenderHelper.instance.ay;
renderer.uvRotateBottom = info.getTexture( ForgeDirection.DOWN ).setFlip( BaseBlockRender.getOrientation( ForgeDirection.DOWN, forward, up ) );
renderer.uvRotateTop = info.getTexture( ForgeDirection.UP ).setFlip( BaseBlockRender.getOrientation( ForgeDirection.UP, forward, up ) );
renderer.uvRotateEast = info.getTexture( ForgeDirection.EAST ).setFlip( BaseBlockRender.getOrientation( ForgeDirection.EAST, forward, up ) );
renderer.uvRotateWest = info.getTexture( ForgeDirection.WEST ).setFlip( BaseBlockRender.getOrientation( ForgeDirection.WEST, forward, up ) );
renderer.uvRotateNorth = info.getTexture( ForgeDirection.NORTH ).setFlip( BaseBlockRender.getOrientation( ForgeDirection.NORTH, forward, up ) );
renderer.uvRotateSouth = info.getTexture( ForgeDirection.SOUTH ).setFlip( BaseBlockRender.getOrientation( ForgeDirection.SOUTH, forward, up ) );
bbr.renderBlockBounds( renderer, minX, minY, minZ, maxX, maxY, maxZ, ax, ay, az );
renderer.renderStandardBlock( blk, x, y, z );
}
@Override
public Block getBlock()
{
return AEApi.instance().blocks().blockMultiPart.block();
}
public void prepareBounds(RenderBlocks renderer)
{
bbr.renderBlockBounds( renderer, minX, minY, minZ, maxX, maxY, maxZ, ax, ay, az );
}
@Override
public void setFacesToRender(EnumSet<ForgeDirection> faces)
{
BusRenderer.instance.renderer.faces = faces;
}
public void renderBlockCurrentBounds(int x, int y, int z, RenderBlocks renderer)
{
if ( !renderThis() )
return;
renderer.renderStandardBlock( renderer.blockAccess.getBlock( x, y, z ), x, y, z );
}
@Override
public void renderFaceCutout(int x, int y, int z, IIcon ico, ForgeDirection face, float edgeThickness, RenderBlocks renderer)
{
if ( !renderThis() )
return;
switch (face)
{
case DOWN:
face = ay.getOpposite();
break;
case EAST:
face = ax;
break;
case NORTH:
face = az.getOpposite();
break;
case SOUTH:
face = az;
break;
case UP:
face = ay;
break;
case WEST:
face = ax.getOpposite();
break;
case UNKNOWN:
break;
default:
break;
}
bbr.renderCutoutFace( blk, ico, x, y, z, renderer, face, edgeThickness );
}
@Override
public void renderFace(int x, int y, int z, IIcon ico, ForgeDirection face, RenderBlocks renderer)
{
if ( !renderThis() )
return;
prepareBounds( renderer );
switch (face)
{
case DOWN:
face = ay.getOpposite();
break;
case EAST:
face = ax;
break;
case NORTH:
face = az.getOpposite();
break;
case SOUTH:
face = az;
break;
case UP:
face = ay;
break;
case WEST:
face = ax.getOpposite();
break;
case UNKNOWN:
break;
default:
break;
}
bbr.renderFace( x, y, z, blk, ico, renderer, face );
}
@Override
public ForgeDirection getWorldX()
{
return ax;
}
@Override
public ForgeDirection getWorldY()
{
return ay;
}
@Override
public ForgeDirection getWorldZ()
{
return az;
}
}