package crazypants.enderio.conduit.geom; import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import net.minecraft.client.renderer.Tessellator; import net.minecraft.util.IIcon; import net.minecraftforge.common.util.ForgeDirection; import com.enderio.core.api.client.render.VertexTransform; import com.enderio.core.client.render.BoundingBox; import com.enderio.core.client.render.RenderUtil; import com.enderio.core.client.render.VertexRotation; import com.enderio.core.client.render.VertexTransformComposite; import com.enderio.core.client.render.VertexTranslation; import com.enderio.core.common.vecmath.Vector3d; import com.enderio.core.common.vecmath.Vertex; import static com.enderio.core.common.util.ForgeDirectionOffsets.offsetScaled; public class ConnectionModeGeometry { private static final EnumMap<ForgeDirection, List<Vertex>> VERTS = new EnumMap<ForgeDirection, List<Vertex>>(ForgeDirection.class); static { float scale = 0.9f; BoundingBox refBB = ConduitGeometryUtil.CORE_BOUNDS; refBB = refBB.scale(scale, scale, scale); refBB = refBB.scale(scale, 1, 1); double offset = (ConduitGeometryUtil.HWIDTH * scale * scale) + ConduitGeometryUtil.CONNECTOR_DEPTH; ForgeDirection dir; Vector3d trans; VertexRotation vrot = new VertexRotation(Math.PI / 2, new Vector3d(0, 1, 0), new Vector3d(0.5, 0.5, 0.5)); VertexTranslation vtrans = new VertexTranslation(0, 0, 0); VertexTransformComposite xform = new VertexTransformComposite(vrot, vtrans); dir = ForgeDirection.SOUTH; trans = offsetScaled(dir, 0.5); trans.sub(offsetScaled(dir, offset)); vtrans.set(trans); VERTS.put(dir, createVerticesForDir(refBB, xform)); dir = ForgeDirection.NORTH; vrot.setAngle(Math.PI + Math.PI / 2); trans = offsetScaled(dir, 0.5); trans.sub(offsetScaled(dir, offset)); vtrans.set(trans); VERTS.put(dir, createVerticesForDir(refBB, xform)); dir = ForgeDirection.EAST; vrot.setAngle(Math.PI); trans = offsetScaled(dir, 0.5); trans.sub(offsetScaled(dir, offset)); vtrans.set(trans); VERTS.put(dir, createVerticesForDir(refBB, xform)); dir = ForgeDirection.WEST; vrot.setAngle(0); trans = offsetScaled(dir, 0.5); trans.sub(offsetScaled(dir, offset)); vtrans.set(trans); VERTS.put(dir, createVerticesForDir(refBB, xform)); vrot.setAxis(new Vector3d(0, 0, 1)); dir = ForgeDirection.UP; vrot.setAngle(-Math.PI / 2); trans = offsetScaled(dir, 0.5); trans.sub(offsetScaled(dir, offset)); vtrans.set(trans); VERTS.put(dir, createVerticesForDir(refBB, xform)); dir = ForgeDirection.DOWN; vrot.setAngle(Math.PI / 2); trans = offsetScaled(dir, 0.5); trans.sub(offsetScaled(dir, offset)); vtrans.set(trans); VERTS.put(dir, createVerticesForDir(refBB, xform)); } private static List<Vertex> createVerticesForDir(BoundingBox refBB, VertexTransform xform) { List<Vertex> result = new ArrayList<Vertex>(24); for (ForgeDirection face : ForgeDirection.VALID_DIRECTIONS) { result.addAll(refBB.getCornersWithUvForFace(face)); } for (Vertex v : result) { xform.apply(v.xyz); xform.applyToNormal(v.normal); } return result; } public static void renderModeConnector(ForgeDirection dir, Offset offset, IIcon tex, boolean tintSides) { List<Vertex> verts = VERTS.get(dir); if (verts == null) { return; } Vector3d trans = ConduitGeometryUtil.instance.getTranslation(dir, offset); float uWidth = tex.getMaxU() - tex.getMinU(); float uScale = uWidth * 0.64f; float minU = tex.getMinU() + (uWidth - uScale); float vScale = tex.getMaxV() - tex.getMinV(); Tessellator tes = Tessellator.instance; for (Vertex v : verts) { if (tintSides) { float cm = 1; if (v.ny() > 0.1) { cm = RenderUtil.getColorMultiplierForFace(ForgeDirection.UP); } else if (v.ny() < -0.1) { cm = RenderUtil.getColorMultiplierForFace(ForgeDirection.DOWN); } else if (v.nx() > 0.1) { cm = RenderUtil.getColorMultiplierForFace(ForgeDirection.EAST); } else if (v.nx() < -0.1) { cm = RenderUtil.getColorMultiplierForFace(ForgeDirection.WEST); } else if (v.nz() > 0.1) { cm = RenderUtil.getColorMultiplierForFace(ForgeDirection.SOUTH); } else if (v.nz() < -0.1) { cm = RenderUtil.getColorMultiplierForFace(ForgeDirection.NORTH); } tes.setColorOpaque_F(cm, cm, cm); } tes.setNormal(v.nx(), v.ny(), v.nz()); tes.addVertexWithUV(v.x() + trans.x, v.y() + trans.y, v.z() + trans.z, minU + (v.u() * uScale), tex.getMinV() + (v.v() * vScale)); } } }