From eb4f0fcc20158100472dd26df46bce02d8b57a2f Mon Sep 17 00:00:00 2001 From: CrushedPixel Date: Tue, 14 Jul 2015 04:25:19 +0200 Subject: [PATCH] Added Preview for Camera's Position and look direction in Path Previews Added getDestination() method to AdvancedPosition to calculate the destination based on a step size and the position's pitch/yaw --- .../replaymod/holders/AdvancedPosition.java | 17 +++ .../renderer/PathPreviewRenderer.java | 104 +++++++++++++++++- .../assets/replaymod/camera_head.png | Bin 0 -> 1254 bytes 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/main/resources/assets/replaymod/camera_head.png diff --git a/src/main/java/eu/crushedpixel/replaymod/holders/AdvancedPosition.java b/src/main/java/eu/crushedpixel/replaymod/holders/AdvancedPosition.java index 4bdb81b8..f1e45518 100755 --- a/src/main/java/eu/crushedpixel/replaymod/holders/AdvancedPosition.java +++ b/src/main/java/eu/crushedpixel/replaymod/holders/AdvancedPosition.java @@ -6,6 +6,9 @@ import lombok.EqualsAndHashCode; import lombok.NoArgsConstructor; import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; +import net.minecraft.util.MathHelper; + +import javax.vecmath.Vector3d; @Data @NoArgsConstructor @@ -48,6 +51,20 @@ public class AdvancedPosition extends Position { return dx * dx + dy * dy + dz * dz; } + public AdvancedPosition getDestination(double stepSize) { + float f2 = MathHelper.cos((float) (Math.toRadians(-yaw) - (float)Math.PI)); + float f3 = MathHelper.sin((float) (Math.toRadians(-yaw) - (float) Math.PI)); + float f4 = -MathHelper.cos((float) (Math.toRadians(-pitch))); + float f5 = MathHelper.sin((float) (Math.toRadians(-pitch))); + Vector3d direction = new Vector3d((double)(f3 * f4), (double)f5, (double)(f2 * f4)); + direction.normalize(); + direction.scale(stepSize); + + Vector3d position = new Vector3d(x, y, z); + position.add(direction); + return new AdvancedPosition(position.getX(), position.getY(), position.getZ(), pitch, yaw, roll, null); + } + @Override public AdvancedPosition newInstance() { return new AdvancedPosition(); diff --git a/src/main/java/eu/crushedpixel/replaymod/renderer/PathPreviewRenderer.java b/src/main/java/eu/crushedpixel/replaymod/renderer/PathPreviewRenderer.java index 113e1d4f..d9439653 100644 --- a/src/main/java/eu/crushedpixel/replaymod/renderer/PathPreviewRenderer.java +++ b/src/main/java/eu/crushedpixel/replaymod/renderer/PathPreviewRenderer.java @@ -12,6 +12,7 @@ import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.Tessellator; import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.entity.Entity; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import org.lwjgl.opengl.GL11; @@ -30,9 +31,12 @@ public class PathPreviewRenderer { private KeyframeList keyframes; + private final ResourceLocation cameraHeadResource = new ResourceLocation("replaymod", "camera_head.png"); + @SubscribeEvent public void renderCameraPath(RenderWorldLastEvent event) { - if(!ReplayHandler.isInReplay() || ReplayHandler.isInPath() || !ReplayMod.replaySettings.showPathPreview() || mc.gameSettings.hideGUI) return; + //if(!ReplayHandler.isInReplay() || ReplayHandler.isInPath() || !ReplayMod.replaySettings.showPathPreview() || mc.gameSettings.hideGUI) return; + if(!ReplayHandler.isInReplay() || !ReplayMod.replaySettings.showPathPreview() || mc.gameSettings.hideGUI) return; Entity entity = ReplayHandler.getCameraEntity(); if(entity == null) return; @@ -90,6 +94,15 @@ public class PathPreviewRenderer { drawPoint(doubleX, doubleY, doubleZ, kf); } + if(ReplayHandler.getPositionKeyframes().size() > 1) { + AdvancedPosition cameraPosition = ReplayHandler.getPositionKeyframes().getInterpolatedValueForTimestamp(ReplayHandler.getRealTimelineCursor(), + ReplayMod.replaySettings.isLinearMovement()); + if(cameraPosition != null) { + GlStateManager.blendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); + drawCamera(doubleX, doubleY, doubleZ, cameraPosition); + } + } + GlStateManager.disableAlpha(); GlStateManager.disableTexture2D(); GlStateManager.disableBlend(); @@ -202,4 +215,93 @@ public class PathPreviewRenderer { GlStateManager.popMatrix(); } + + private void drawCamera(double playerX, double playerY, double playerZ, AdvancedPosition pos) { + GlStateManager.pushMatrix(); + + Tessellator tessellator = Tessellator.getInstance(); + WorldRenderer renderer = tessellator.getWorldRenderer(); + + mc.renderEngine.bindTexture(cameraHeadResource); + + double x = pos.getX() - playerX; + double y = pos.getY() - playerY; + double z = pos.getZ() - playerZ; + + GlStateManager.translate(x, y + 1.4, z); + + GL11.glNormal3f(0, 1, 0); + + //draw the position line + AdvancedPosition pos2 = pos.getDestination(2); + + GlStateManager.enableDepth(); + GlStateManager.disableLighting(); + GlStateManager.disableTexture2D(); + GlStateManager.enableBlend(); + renderer.startDrawing(1); + + renderer.setColorRGBA_I(Color.GREEN.getRGB(), 170); + + renderer.addVertex(pos2.getX() - pos.getX(), pos2.getY() - pos.getY(), pos2.getZ() - pos.getZ()); + renderer.addVertex(0, 0, 0); + + Tessellator.getInstance().draw(); + + GlStateManager.enableTexture2D(); + + GlStateManager.rotate((float) -pos.getYaw(), 0, 1, 0); + GlStateManager.rotate((float) pos.getPitch(), 1, 0, 0); + GlStateManager.rotate((float) pos.getRoll(), 0, 0, 1); + + float cubeSize = 0.5f; + + x = y = z = -cubeSize/2; + + renderer.startDrawingQuads(); + + renderer.setColorRGBA_I(Color.WHITE.getRGB(), 200); + + //back + renderer.addVertexWithUV(x, y + cubeSize, z, 3 * 8 / 64f, 8 / 64f); + renderer.addVertexWithUV(x + cubeSize, y + cubeSize, z, 4*8/64f, 8/64f); + renderer.addVertexWithUV(x + cubeSize, y, z, 4*8/64f, 2*8/64f); + renderer.addVertexWithUV(x, y, z, 3*8/64f, 2*8/64f); + + //front + renderer.addVertexWithUV(x + cubeSize, y, z + cubeSize, 2 * 8 / 64f, 2*8/64f); + renderer.addVertexWithUV(x + cubeSize, y + cubeSize, z + cubeSize, 2 * 8 / 64f, 8/64f); + renderer.addVertexWithUV(x, y + cubeSize, z + cubeSize, 8 / 64f, 8 / 64f); + renderer.addVertexWithUV(x, y, z + cubeSize, 8 / 64f, 2*8/64f); + + //left + renderer.addVertexWithUV(x + cubeSize, y + cubeSize, z, 0, 8/64f); + renderer.addVertexWithUV(x + cubeSize, y + cubeSize, z + cubeSize, 8/64f, 8/64f); + renderer.addVertexWithUV(x + cubeSize, y, z + cubeSize, 8/64f, 2*8/64f); + renderer.addVertexWithUV(x+cubeSize,y,z, 0, 2*8/64f); + + //right + renderer.addVertexWithUV(x, y + cubeSize, z + cubeSize, 2*8/64f, 8/64f); + renderer.addVertexWithUV(x, y + cubeSize, z, 3*8/64f, 8/64f); + renderer.addVertexWithUV(x, y, z, 3*8/64f, 2*8/64f); + renderer.addVertexWithUV(x, y, z + cubeSize, 2 * 8 / 64f, 2 * 8 / 64f); + + //bottom + renderer.addVertexWithUV(x + cubeSize, y, z, 3*8/64f, 0); + renderer.addVertexWithUV(x + cubeSize, y, z + cubeSize, 3*8/64f, 8/64f); + renderer.addVertexWithUV(x, y, z + cubeSize, 2*8/64f, 8/64f); + renderer.addVertexWithUV(x, y, z, 2 * 8 / 64f, 0); + + //top + renderer.addVertexWithUV(x, y + cubeSize, z, 8/64f, 0); + renderer.addVertexWithUV(x, y + cubeSize, z + cubeSize, 8/64f, 8/64f); + renderer.addVertexWithUV(x + cubeSize, y + cubeSize, z + cubeSize, 2*8/64f, 8/64f); + renderer.addVertexWithUV(x + cubeSize, y + cubeSize, z, 2 * 8 / 64f, 0); + + Tessellator.getInstance().draw(); + + renderer.setTranslation(0, 0, 0); + + GlStateManager.popMatrix(); + } } diff --git a/src/main/resources/assets/replaymod/camera_head.png b/src/main/resources/assets/replaymod/camera_head.png new file mode 100644 index 0000000000000000000000000000000000000000..d4503970bad41c32ab6c45e44c10f48b8b897c24 GIT binary patch literal 1254 zcmV<2L{R1anD5 zK~#9!?OHu(6hRdJF2o$!yUP+ec1Z}Rm;^!68SPEhx8WaS@RzwgX zcCoUu&}y-;iYOXQTq98k2^)fObGZ$hpl318?acmVHusagWIi}rfKde1GFa*-is_~ z7xnyJMW(m6x3ZfLu(-IGNeu)16sMk#qJGqPD>0@mO!+7U48w?Axv}T8Qmzo51q{PL zrBX@7^0n>;5cOClBOb1;!h$x@hi6}!!d{?Sb&5>14%qI^QBH#`I1L7Fe)0Si*Z(+w ziR;hK&c5T(;6srR(AOY7Q7Wb`=2NxE7SG4(;G6 zPGI@hyXqJKZhU=X0dFrj{KK6&0~|Pj+b^Hsh~9;HYYhM}J~BpRe*Wa2;LssJQM`UO zOa5J#{LjpU%V)Dh#y>tZ#P>%>w+{iwwRU8^d}kkNSQh#9_XDa5C?ugwVQ`p`TU~9=N>It_)jY7ivA_=&3gL=q8u1YAvr4h@ zY`llC;L(pa)vo>J6OR5p0nB?M-)BEVRXRxL$5#~pF7fM{oiJd1V}VmNHb=0^6bjLb zscKM$wrx9j-6*2~SXnE3msL7oJDc@oKsCAfSP(i^m=AhX(>%qf;(oA(P*oz!#kO5Tv9l3#ZD&G44FL-D3_UNwaZ6CL3LMwM;U4zG$R7X>Sux)7jt{;n{b!Z} z?O?u|aNl0{^2O;pCdoGg(TT9wm8&u%jv-BZ8Hx&(d}kj{-!ZEO^ULNt`-seavZy)t zEFVa=taqbk0|^NU2?+@a2?+@a2?+@a2@%x2j$QNq0$=@q^!`n*`uoWEP}k>8UwORF z_5ap009#%IIPWjn<$Yj)7-OU|2PEBJpmgfo2hZ1MeY;YRANM|`J5I3ro3Q?$8V1n% zVp!RYtM9Yb-?04ztr!A{Doa#p$^sU;z7KK$Tk~hx&>*zei{7GM_U|ufbp5|+3}E*V z`1coxz+c)Dsq3YN0dxlmMQEZE7^8}BSN={?|8I%`YDt7qMNO()+*qoTU`?AW5MSJ^ zWeZHh8Bpu~0(HGZ*t@FI!PWj#6#_fmU%-X|8{_q)dFs~zQQ4oi8(I7R2c@R*7phAw QiU0rr07*qoM6N<$f_6km00000 literal 0 HcmV?d00001