package com.carpentersblocks.renderer.helper;
import net.minecraft.block.BlockGrass;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.util.IIcon;
import net.minecraftforge.common.util.ForgeDirection;
import com.carpentersblocks.renderer.BlockHandlerSloped;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class RenderHelper extends VertexHelper {
private static boolean rotationOverride = false;
protected static int rotation;
private static double uMin;
private static double uMax;
private static double vMin;
private static double vMax;
protected static double xMin;
protected static double xMax;
protected static double yMin;
protected static double yMax;
protected static double zMin;
protected static double zMax;
protected static double uTL;
protected static double vTL;
protected static double uBL;
protected static double vBL;
protected static double uBR;
protected static double vBR;
protected static double uTR;
protected static double vTR;
public static final double OFFSET_MAX = 2.0D / 1024.0D;
public static final double OFFSET_MIN = 1.0D / 1024.0D;
public static double renderOffset;
public static void setOffset(double offset)
{
renderOffset = offset;
}
public static void clearOffset()
{
renderOffset = 0.0D;
}
public static void setTextureRotationOverride(int in_rotation)
{
rotationOverride = true;
rotation = in_rotation;
}
public static void clearTextureRotationOverride()
{
rotationOverride = false;
}
/**
* Sets UV coordinates for each corner based on side rotation.
*/
private static void setCornerUV(double t_uTL, double t_vTL, double t_uBL, double t_vBL, double t_uBR, double t_vBR, double t_uTR, double t_vTR)
{
uTL = t_uTL;
vTL = t_vTL;
uBL = t_uBL;
vBL = t_vBL;
uBR = t_uBR;
vBR = t_vBR;
uTR = t_uTR;
vTR = t_vTR;
}
/**
* Will populate render bounds and icon u, v translations.
*/
protected static void prepareRender(RenderBlocks renderBlocks, ForgeDirection side, double x, double y, double z, IIcon icon)
{
/* Enforce default floating icons */
if (icon == BlockGrass.getIconSideOverlay() || icon.getIconName().contains("overlay/overlay_") && icon.getIconName().endsWith("_side")) {
setFloatingIcon();
}
/* Set render bounds with offset. */
xMin = x + renderBlocks.renderMinX - renderOffset;
xMax = x + renderBlocks.renderMaxX + renderOffset;
yMin = y + renderBlocks.renderMinY - renderOffset;
yMax = y + renderBlocks.renderMaxY + renderOffset;
zMin = z + renderBlocks.renderMinZ - renderOffset;
zMax = z + renderBlocks.renderMaxZ + renderOffset;
// Sloppy way to help prevent z-fighting on sloped faces.
// Working on a better solution...
if (BlockHandlerSloped.isSideSloped) {
switch (side) {
case DOWN:
yMin -= renderOffset;
yMax -= renderOffset;
break;
case UP:
yMin += renderOffset;
yMax += renderOffset;
break;
case NORTH:
zMin -= renderOffset;
zMax -= renderOffset;
break;
case SOUTH:
zMin += renderOffset;
zMax += renderOffset;
break;
case WEST:
xMin -= renderOffset;
xMax -= renderOffset;
break;
case EAST:
xMin += renderOffset;
xMax += renderOffset;
break;
default: {}
}
}
/* Set u, v for icon with rotation. */
if (!rotationOverride) {
switch (side) {
case DOWN:
rotation = renderBlocks.uvRotateBottom;
break;
case UP:
rotation = renderBlocks.uvRotateTop;
break;
case NORTH:
rotation = renderBlocks.uvRotateNorth;
break;
case SOUTH:
rotation = renderBlocks.uvRotateSouth;
break;
case WEST:
rotation = renderBlocks.uvRotateWest;
break;
case EAST:
rotation = renderBlocks.uvRotateEast;
break;
default: {}
}
}
switch (side) {
case DOWN:
switch (rotation) {
case 0:
uMin = icon.getInterpolatedU(renderBlocks.renderMinX * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMaxX * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinZ * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxZ * 16.0D);
setCornerUV(uMax, vMax, uMax, vMin, uMin, vMin, uMin, vMax);
break;
case 1:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxZ * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMinZ * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinX * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxX * 16.0D);
setCornerUV(uMin, vMax, uMax, vMax, uMax, vMin, uMin, vMin);
break;
case 2:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMinX * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxX * 16.0D);
vMin = icon.getInterpolatedV(16.0D - renderBlocks.renderMinZ * 16.0D);
vMax = icon.getInterpolatedV(16.0D - renderBlocks.renderMaxZ * 16.0D);
setCornerUV(uMax, vMax, uMax, vMin, uMin, vMin, uMin, vMax);
break;
case 3:
uMin = icon.getInterpolatedU(renderBlocks.renderMaxZ * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMinZ * 16.0D);
vMin = icon.getInterpolatedV(16.0D - renderBlocks.renderMinX * 16.0D);
vMax = icon.getInterpolatedV(16.0D - renderBlocks.renderMaxX * 16.0D);
setCornerUV(uMin, vMax, uMax, vMax, uMax, vMin, uMin, vMin);
break;
}
break;
case UP:
switch (rotation) {
case 0:
uMin = icon.getInterpolatedU(renderBlocks.renderMinX * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMaxX * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinZ * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxZ * 16.0D);
setCornerUV(uMax, vMax, uMax, vMin, uMin, vMin, uMin, vMax);
break;
case 1:
uMin = icon.getInterpolatedU(renderBlocks.renderMaxZ * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMinZ * 16.0D);
vMin = icon.getInterpolatedV(16.0D - renderBlocks.renderMinX * 16.0D);
vMax = icon.getInterpolatedV(16.0D - renderBlocks.renderMaxX * 16.0D);
setCornerUV(uMin, vMax, uMax, vMax, uMax, vMin, uMin, vMin);
break;
case 2:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMinX * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxX * 16.0D);
vMin = icon.getInterpolatedV(16.0D - renderBlocks.renderMinZ * 16.0D);
vMax = icon.getInterpolatedV(16.0D - renderBlocks.renderMaxZ * 16.0D);
setCornerUV(uMax, vMax, uMax, vMin, uMin, vMin, uMin, vMax);
break;
case 3:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxZ * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMinZ * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinX * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxX * 16.0D);
setCornerUV(uMin, vMax, uMax, vMax, uMax, vMin, uMin, vMin);
break;
}
break;
case NORTH:
switch (rotation) {
case 0:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxX * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMinX * 16.0D);
vMin = icon.getInterpolatedV(16.0D - (floatingIcon ? 1.0D - (renderBlocks.renderMaxY - renderBlocks.renderMinY) : renderBlocks.renderMinY) * 16.0D);
vMax = icon.getInterpolatedV(16.0D - (floatingIcon ? 1.0D : renderBlocks.renderMaxY) * 16.0D);
setCornerUV(uMin, vMax, uMin, vMin, uMax, vMin, uMax, vMax);
break;
case 1:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxY * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMinY * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMaxX * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMinX * 16.0D);
setCornerUV(uMin, vMin, uMax, vMin, uMax, vMax, uMin, vMax);
break;
case 2:
uMin = icon.getInterpolatedU(renderBlocks.renderMaxX * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMinX * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinY * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxY * 16.0D);
setCornerUV(uMin, vMax, uMin, vMin, uMax, vMin, uMax, vMax);
break;
case 3:
uMin = icon.getInterpolatedU(renderBlocks.renderMaxY * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMinY * 16.0D);
vMin = icon.getInterpolatedV(16.0D - renderBlocks.renderMaxX * 16.0D);
vMax = icon.getInterpolatedV(16.0D - renderBlocks.renderMinX * 16.0D);
setCornerUV(uMin, vMin, uMax, vMin, uMax, vMax, uMin, vMax);
break;
}
break;
case SOUTH:
switch (rotation) {
case 0:
uMin = icon.getInterpolatedU(renderBlocks.renderMinX * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMaxX * 16.0D);
vMin = icon.getInterpolatedV(16.0D - (floatingIcon ? 1.0D - (renderBlocks.renderMaxY - renderBlocks.renderMinY) : renderBlocks.renderMinY) * 16.0D);
vMax = icon.getInterpolatedV(16.0D - (floatingIcon ? 1.0D : renderBlocks.renderMaxY) * 16.0D);
setCornerUV(uMin, vMax, uMin, vMin, uMax, vMin, uMax, vMax);
break;
case 1:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxY * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMinY * 16.0D);
vMin = icon.getInterpolatedV(16.0D - renderBlocks.renderMinX * 16.0D);
vMax = icon.getInterpolatedV(16.0D - renderBlocks.renderMaxX * 16.0D);
setCornerUV(uMin, vMin, uMax, vMin, uMax, vMax, uMin, vMax);
break;
case 2:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMinX * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxX * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinY * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxY * 16.0D);
setCornerUV(uMin, vMax, uMin, vMin, uMax, vMin, uMax, vMax);
break;
case 3:
uMin = icon.getInterpolatedU(renderBlocks.renderMaxY * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMinY * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinX * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxX * 16.0D);
setCornerUV(uMin, vMin, uMax, vMin, uMax, vMax, uMin, vMax);
break;
}
break;
case WEST:
switch (rotation) {
case 0:
uMin = icon.getInterpolatedU(renderBlocks.renderMinZ * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMaxZ * 16.0D);
vMax = icon.getInterpolatedV(16.0D - (floatingIcon ? 1.0D : renderBlocks.renderMaxY) * 16.0D);
vMin = icon.getInterpolatedV(16.0D - (floatingIcon ? 1.0D - (renderBlocks.renderMaxY - renderBlocks.renderMinY) : renderBlocks.renderMinY) * 16.0D);
setCornerUV(uMin, vMax, uMin, vMin, uMax, vMin, uMax, vMax);
break;
case 1:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxY * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMinY * 16.0D);
vMin = icon.getInterpolatedV(16.0D - renderBlocks.renderMinZ * 16.0D);
vMax = icon.getInterpolatedV(16.0D - renderBlocks.renderMaxZ * 16.0D);
setCornerUV(uMin, vMin, uMax, vMin, uMax, vMax, uMin, vMax);
break;
case 2:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMinZ * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxZ * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinY * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxY * 16.0D);
setCornerUV(uMin, vMax, uMin, vMin, uMax, vMin, uMax, vMax);
break;
case 3:
uMin = icon.getInterpolatedU(renderBlocks.renderMaxY * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMinY * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinZ * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxZ * 16.0D);
setCornerUV(uMin, vMin, uMax, vMin, uMax, vMax, uMin, vMax);
break;
}
break;
case EAST:
switch (rotation) {
case 0:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxZ * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMinZ * 16.0D);
vMax = icon.getInterpolatedV(16.0D - (floatingIcon ? 1.0D : renderBlocks.renderMaxY) * 16.0D);
vMin = icon.getInterpolatedV(16.0D - (floatingIcon ? 1.0D - (renderBlocks.renderMaxY - renderBlocks.renderMinY) : renderBlocks.renderMinY) * 16.0D);
setCornerUV(uMin, vMax, uMin, vMin, uMax, vMin, uMax, vMax);
break;
case 1:
uMin = icon.getInterpolatedU(16.0D - renderBlocks.renderMaxY * 16.0D);
uMax = icon.getInterpolatedU(16.0D - renderBlocks.renderMinY * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMaxZ * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMinZ * 16.0D);
setCornerUV(uMin, vMin, uMax, vMin, uMax, vMax, uMin, vMax);
break;
case 2:
uMin = icon.getInterpolatedU(renderBlocks.renderMaxZ * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMinZ * 16.0D);
vMin = icon.getInterpolatedV(renderBlocks.renderMinY * 16.0D);
vMax = icon.getInterpolatedV(renderBlocks.renderMaxY * 16.0D);
setCornerUV(uMin, vMax, uMin, vMin, uMax, vMin, uMax, vMax);
break;
case 3:
uMin = icon.getInterpolatedU(renderBlocks.renderMaxY * 16.0D);
uMax = icon.getInterpolatedU(renderBlocks.renderMinY * 16.0D);
vMin = icon.getInterpolatedV(16.0D - renderBlocks.renderMaxZ * 16.0D);
vMax = icon.getInterpolatedV(16.0D - renderBlocks.renderMinZ * 16.0D);
setCornerUV(uMin, vMin, uMax, vMin, uMax, vMax, uMin, vMax);
break;
}
break;
default: {}
}
}
/**
* Renders the given texture to the bottom face of the block. Args: slope, x, y, z, texture
*/
public static void renderFaceYNeg(RenderBlocks renderBlocks, double x, double y, double z, IIcon icon)
{
prepareRender(renderBlocks, ForgeDirection.DOWN, x, y, z, icon);
setupVertex(renderBlocks, xMin, yMin, zMax, uTR, vTR, SOUTHWEST);
setupVertex(renderBlocks, xMin, yMin, zMin, uBR, vBR, NORTHWEST);
setupVertex(renderBlocks, xMax, yMin, zMin, uBL, vBL, NORTHEAST);
setupVertex(renderBlocks, xMax, yMin, zMax, uTL, vTL, SOUTHEAST);
}
/**
* Renders the given texture to the top face of the block. Args: slope, x, y, z, texture
*/
public static void renderFaceYPos(RenderBlocks renderBlocks, double x, double y, double z, IIcon icon)
{
prepareRender(renderBlocks, ForgeDirection.UP, x, y, z, icon);
setupVertex(renderBlocks, xMax, yMax, zMax, uTL, vTL, SOUTHEAST);
setupVertex(renderBlocks, xMax, yMax, zMin, uBL, vBL, NORTHEAST);
setupVertex(renderBlocks, xMin, yMax, zMin, uBR, vBR, NORTHWEST);
setupVertex(renderBlocks, xMin, yMax, zMax, uTR, vTR, SOUTHWEST);
}
/**
* Renders the given texture to the North face of the block. Args: slope, x, y, z, texture
*/
public static void renderFaceZNeg(RenderBlocks renderBlocks, double x, double y, double z, IIcon icon)
{
prepareRender(renderBlocks, ForgeDirection.NORTH, x, y, z, icon);
setupVertex(renderBlocks, xMax, yMax, zMin, uTL, vTL, TOP_LEFT );
setupVertex(renderBlocks, xMax, yMin, zMin, uBL, vBL, BOTTOM_LEFT );
setupVertex(renderBlocks, xMin, yMin, zMin, uBR, vBR, BOTTOM_RIGHT);
setupVertex(renderBlocks, xMin, yMax, zMin, uTR, vTR, TOP_RIGHT );
}
/**
* Renders the given texture to the South face of the block. Args: slope, x, y, z, texture
*/
public static void renderFaceZPos(RenderBlocks renderBlocks, double x, double y, double z, IIcon icon)
{
prepareRender(renderBlocks, ForgeDirection.SOUTH, x, y, z, icon);
setupVertex(renderBlocks, xMin, yMax, zMax, uTL, vTL, TOP_LEFT );
setupVertex(renderBlocks, xMin, yMin, zMax, uBL, vBL, BOTTOM_LEFT );
setupVertex(renderBlocks, xMax, yMin, zMax, uBR, vBR, BOTTOM_RIGHT);
setupVertex(renderBlocks, xMax, yMax, zMax, uTR, vTR, TOP_RIGHT );
}
/**
* Renders the given texture to the West face of the block. Args: slope, x, y, z, texture
*/
public static void renderFaceXNeg(RenderBlocks renderBlocks, double x, double y, double z, IIcon icon)
{
prepareRender(renderBlocks, ForgeDirection.WEST, x, y, z, icon);
setupVertex(renderBlocks, xMin, yMax, zMin, uTL, vTL, TOP_LEFT );
setupVertex(renderBlocks, xMin, yMin, zMin, uBL, vBL, BOTTOM_LEFT );
setupVertex(renderBlocks, xMin, yMin, zMax, uBR, vBR, BOTTOM_RIGHT);
setupVertex(renderBlocks, xMin, yMax, zMax, uTR, vTR, TOP_RIGHT );
}
/**
* Renders the given texture to the East face of the block. Args: slope, x, y, z, texture
*/
public static void renderFaceXPos(RenderBlocks renderBlocks, double x, double y, double z, IIcon icon)
{
prepareRender(renderBlocks, ForgeDirection.EAST, x, y, z, icon);
setupVertex(renderBlocks, xMax, yMax, zMax, uTL, vTL, TOP_LEFT );
setupVertex(renderBlocks, xMax, yMin, zMax, uBL, vBL, BOTTOM_LEFT );
setupVertex(renderBlocks, xMax, yMin, zMin, uBR, vBR, BOTTOM_RIGHT);
setupVertex(renderBlocks, xMax, yMax, zMin, uTR, vTR, TOP_RIGHT );
}
}