package codechicken.translocator; import java.util.Map; import org.lwjgl.opengl.GL11; import codechicken.core.ClientUtils; import codechicken.lib.math.MathHelper; import codechicken.lib.colour.CustomGradient; import codechicken.lib.render.CCModel; import codechicken.lib.render.CCRenderState; import codechicken.lib.render.RenderUtils; import codechicken.lib.vec.Matrix4; import codechicken.lib.vec.SwapYZ; import codechicken.lib.vec.Vector3; import codechicken.translocator.TileItemTranslocator.MovingItem; import codechicken.translocator.TileLiquidTranslocator.MovingLiquid; import codechicken.translocator.TileTranslocator.Attachment; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.util.ResourceLocation; import net.minecraftforge.fluids.FluidStack; import static codechicken.lib.vec.Rotation.*; public class TileTranslocatorRenderer extends TileEntitySpecialRenderer { public static Vector3[] sidePos = new Vector3[]{ new Vector3(0.5, 0, 0.5), new Vector3(0.5, 1, 0.5), new Vector3(0.5, 0.5, 0), new Vector3(0.5, 0.5, 1), new Vector3(0, 0.5, 0.5), new Vector3(1, 0.5, 0.5)}; public static Vector3[] sideVec = new Vector3[]{ new Vector3( 0,-1, 0), new Vector3( 0, 1, 0), new Vector3( 0, 0,-1), new Vector3( 0, 0, 1), new Vector3(-1, 0, 0), new Vector3( 1, 0, 0)}; public static CCModel[] plates = new CCModel[6]; public static CCModel insert; static { Map<String, CCModel> models = CCModel.parseObjModels(new ResourceLocation("translocator", "models/model.obj"), new SwapYZ()); plates[0] = models.get("Plate"); insert = models.get("Insert"); CCModel.generateSidedModels(plates, 0, new Vector3()); } private CustomGradient gradient = new CustomGradient(new ResourceLocation("translocator", "textures/grad.png")); public TileTranslocatorRenderer() { } @Override public void renderTileEntityAt(TileEntity tileentity, double x, double y, double z, float f) { TileTranslocator ttrans = (TileTranslocator)tileentity; double time = ClientUtils.getRenderTime(); CCRenderState.reset(); CCRenderState.changeTexture("translocator:textures/tex.png"); CCRenderState.pullLightmap(); CCRenderState.useNormals = true; CCRenderState.setColour(-1); CCRenderState.startDrawing(4); for(int i = 0; i < 6; i++) { Attachment a = ttrans.attachments[i]; if(a != null) renderAttachment(i, ttrans.getBlockMetadata(), MathHelper.interpolate(a.b_insertpos, a.a_insertpos, f), a.getIconIndex(), x, y, z); } CCRenderState.draw(); if(ttrans instanceof TileItemTranslocator) { TileItemTranslocator titrans = (TileItemTranslocator)ttrans; for(MovingItem m : titrans.movingItems) { GL11.glPushMatrix(); double d = MathHelper.interpolate(m.b_progress, m.a_progress, f); Vector3 pos = getPath(m.src, m.dst, d) .add(itemFloat(m.src, m.dst, d)); GL11.glTranslated(x+pos.x, y+pos.y-0.06, z+pos.z); GL11.glScaled(0.35, 0.35, 0.35); RenderUtils.renderItemUniform(m.stack); GL11.glPopMatrix(); } } if(ttrans instanceof TileLiquidTranslocator) { TileLiquidTranslocator tltrans = (TileLiquidTranslocator)ttrans; for(MovingLiquid m : tltrans.movingLiquids()) { double start = MathHelper.interpolate(m.b_start, m.a_start, f); double end = MathHelper.interpolate(m.b_end, m.a_end, f); drawLiquidSpiral(m.src, m.dst, m.liquid, start, end, time, 0, x, y, z); if(m.fast) drawLiquidSpiral(m.src, m.dst, m.liquid, start, end, time, 0.5, x, y, z); } } GL11.glDisable(GL11.GL_LIGHTING); GL11.glEnable(GL11.GL_BLEND); GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); CCRenderState.changeTexture("translocator:textures/particle.png"); CCRenderState.startDrawing(7); for(int src = 0; src < 6; src++) { Attachment asrc = ttrans.attachments[src]; if(asrc == null || !asrc.a_eject) continue; for(int dst = 0; dst < 6; dst++) { Attachment adst = ttrans.attachments[dst]; if(adst != null && !adst.a_eject) renderLink(src, dst, time, ttrans.xCoord, ttrans.yCoord, ttrans.zCoord); } } CCRenderState.draw(); GL11.glDisable(GL11.GL_BLEND); GL11.glEnable(GL11.GL_LIGHTING); } private void drawLiquidSpiral(int src, int dst, FluidStack stack, double start, double end, double time, double theta0, double x, double y, double z) { IIcon tex = RenderUtils.prepareFluidRender(stack, 255); CCRenderState.startDrawing(7); Tessellator t = Tessellator.instance; t.setTranslation(x, y, z); Vector3[] last = new Vector3[]{new Vector3(), new Vector3(), new Vector3(), new Vector3()}; Vector3[] next = new Vector3[]{new Vector3(), new Vector3(), new Vector3(), new Vector3()}; double tess = 0.05; Vector3 a = getPerp(src, dst); boolean rev = sum(a.copy().crossProduct(getPathNormal(src, dst, 0))) != sum(sideVec[src]); for(double di = end; di <= start; di+=tess) { Vector3 b = getPathNormal(src, dst, di); Vector3 c = getPath(src, dst, di); if(rev) b.negate(); double r = (2*di-time/10+theta0+dst/6)*2*Math.PI; double sz = 0.1; Vector3 p = c.add(a.copy().multiply(MathHelper.sin(r)*sz)).add(b.copy().multiply(MathHelper.cos(r)*sz)); double s1 = 0.02; double s2 =-0.02; next[0].set(p).add(a.x*s1+b.x*s1, a.y*s1+b.y*s1, a.z*s1+b.z*s1); next[1].set(p).add(a.x*s2+b.x*s1, a.y*s2+b.y*s1, a.z*s2+b.z*s1); next[2].set(p).add(a.x*s2+b.x*s2, a.y*s2+b.y*s2, a.z*s2+b.z*s2); next[3].set(p).add(a.x*s1+b.x*s2, a.y*s1+b.y*s2, a.z*s1+b.z*s2); if(di > end) { double u1 = tex.getInterpolatedU(Math.abs(di)*16); double u2 = tex.getInterpolatedU(Math.abs(di-tess)*16); for(int i = 0; i < 4; i++) { int j = (i+1)%4; Vector3 axis = next[j].copy().subtract(next[i]); double v1 = tex.getInterpolatedV(Math.abs(next[i].scalarProject(axis))*16); double v2 = tex.getInterpolatedV(Math.abs(next[j].scalarProject(axis))*16); t.addVertexWithUV(next[i].x, next[i].y, next[i].z, u1, v1); t.addVertexWithUV(next[j].x, next[j].y, next[j].z, u1, v2); t.addVertexWithUV(last[j].x, last[j].y, last[j].z, u2, v2); t.addVertexWithUV(last[i].x, last[i].y, last[i].z, u2, v1); } } Vector3[] tmp = last; last = next; next = tmp; } CCRenderState.draw(); t.setTranslation(0, 0, 0); RenderUtils.postFluidRender(); } private double sum(Vector3 v) { return v.x+v.y+v.z; } private void renderLink(int src, int dst, double time, int x, int y, int z) { double d = ((time+src+dst*2)%10)/6; //0 is head for(int n = 0; n < 20; n++) { double dn = d-n*0.1; int spriteX = (int) (7-n*1.5-d*2); if(!MathHelper.between(0, dn, 1) || spriteX < 0) continue; Vector3 pos = getPath(src, dst, dn).add(x, y, z); double b = 1;//d*0.6+0.4; double s = 1;//d*0.6+0.4; double u1 = spriteX/8D; double u2 = u1+1/8D; double v1 = 0; double v2 = 1; RenderParticle.render(pos.x, pos.y, pos.z, gradient.getColour((dn-0.5)*1.2+0.5).multiplyC(b), s*0.12, u1, v1, u2, v2); } } private Vector3 itemFloat(int src, int dst, double d) { return getPerp(src, dst).multiply(0.01*MathHelper.sin(d*4*Math.PI)); } public static Vector3 getPath(int src, int dst, double d) { Vector3 v; if((src^1) == dst)//opposite v = sideVec[src^1].copy().multiply(d); else { Vector3 vsrc = sideVec[src^1]; Vector3 vdst = sideVec[dst^1]; Vector3 a = vsrc.copy().multiply(5/16D); Vector3 b = vdst.copy().multiply(6/16D); double sind = MathHelper.sin(d*Math.PI/2); double cosd = MathHelper.cos(d*Math.PI/2); v = a.multiply(sind).add(b.multiply(cosd-1)).add(vsrc.copy().multiply(3/16D)); } return v.add(sidePos[src]); } public static Vector3 getPerp(int src, int dst) { if((src^1) == dst) return sideVec[(src+2)%6].copy(); for(int i = 0; i < 3; i++) if(i != src/2 && i != dst/2) return sideVec[i*2].copy(); return null; } private static Vector3 getPathNormal(int src, int dst, double d) { if((src^1) == dst) return sideVec[(src+4)%6].copy(); double sind = MathHelper.sin(d*Math.PI/2); double cosd = MathHelper.cos(d*Math.PI/2); Vector3 vsrc = sideVec[src^1].copy(); Vector3 vdst = sideVec[dst^1].copy(); return vsrc.multiply(sind).add(vdst.multiply(cosd)).normalize(); } public static void renderAttachment(int i, int type, double insertpos, int field, double x, double y, double z) { double tx = field/64D; double ty = type/2D; plates[i].render(x+0.5, y+0.5, z+0.5, tx, ty); Matrix4 matrix = new Matrix4() .translate(new Vector3(x+0.5, y+0.5, z+0.5)) .apply(sideRotations[i]) .translate(new Vector3(0, -0.5, 0)) .scale(new Vector3(1, insertpos*2/3+1/3D, 1)); insert.render(matrix, tx, ty); } }