From 5427616ceb61f75d56099455aff03990f67174fc Mon Sep 17 00:00:00 2001 From: CrushedPixel Date: Sat, 25 Jul 2015 14:11:06 +0200 Subject: [PATCH] Reworked ReplayProcess to get rid of own Interpolation instances (as these can be handled by the KeyframeLists) Camera Paths are now started from the current cursor position, using Ctrl-click the path always starts from the beginning --- .../eu/crushedpixel/replaymod/ReplayMod.java | 2 +- .../replaymod/gui/GuiRenderSettings.java | 2 +- .../gui/overlay/GuiReplayOverlay.java | 2 +- .../replaymod/replay/ReplayHandler.java | 4 +- .../replaymod/replay/ReplayProcess.java | 194 +++++------------- 5 files changed, 58 insertions(+), 146 deletions(-) diff --git a/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java b/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java index ef517907..07471866 100755 --- a/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java +++ b/src/main/java/eu/crushedpixel/replaymod/ReplayMod.java @@ -350,7 +350,7 @@ public class ReplayMod { System.out.println("Rendering started..."); try { - ReplayProcess.startReplayProcess(options); + ReplayProcess.startReplayProcess(options, true); } catch (Throwable t) { t.printStackTrace(); FMLCommonHandler.instance().exitJava(1, false); diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/GuiRenderSettings.java b/src/main/java/eu/crushedpixel/replaymod/gui/GuiRenderSettings.java index 6ab84830..24fc9c09 100644 --- a/src/main/java/eu/crushedpixel/replaymod/gui/GuiRenderSettings.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/GuiRenderSettings.java @@ -457,7 +457,7 @@ public class GuiRenderSettings extends GuiScreen implements GuiReplayOverlay.NoO if(FMLClientHandler.instance().hasOptifine()) { mc.displayGuiScreen(new GuiErrorScreen(I18n.format("replaymod.gui.rendering.error.title"), I18n.format("replaymod.gui.rendering.error.optifine"))); } else { - ReplayHandler.startPath(options); + ReplayHandler.startPath(options, true); } } diff --git a/src/main/java/eu/crushedpixel/replaymod/gui/overlay/GuiReplayOverlay.java b/src/main/java/eu/crushedpixel/replaymod/gui/overlay/GuiReplayOverlay.java index 123be5de..1cf580fa 100755 --- a/src/main/java/eu/crushedpixel/replaymod/gui/overlay/GuiReplayOverlay.java +++ b/src/main/java/eu/crushedpixel/replaymod/gui/overlay/GuiReplayOverlay.java @@ -119,7 +119,7 @@ public class GuiReplayOverlay extends Gui { private final GuiElement buttonPlay = texturedButton(BUTTON_PLAY_PATH_X, BOTTOM_ROW, 0, 0, 20, new Runnable() { @Override public void run() { - ReplayHandler.startPath(null); + ReplayHandler.startPath(null, GuiScreen.isCtrlKeyDown()); } }, "replaymod.gui.ingame.menu.playpath"); diff --git a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java index a1f0b9f3..525855e4 100755 --- a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java +++ b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayHandler.java @@ -165,10 +165,10 @@ public class ReplayHandler { return currentEntity; } - public static void startPath(RenderOptions renderOptions) { + public static void startPath(RenderOptions renderOptions, boolean fromStart) { if(!ReplayHandler.isInPath()) { try { - ReplayProcess.startReplayProcess(renderOptions); + ReplayProcess.startReplayProcess(renderOptions, fromStart); } catch (ReportedException e) { // We have to manually unwrap OOM errors as Minecraft doesn't handle them when they're wrapped Throwable prevCause = null; diff --git a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayProcess.java b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayProcess.java index 181a09dc..602926e9 100755 --- a/src/main/java/eu/crushedpixel/replaymod/replay/ReplayProcess.java +++ b/src/main/java/eu/crushedpixel/replaymod/replay/ReplayProcess.java @@ -5,9 +5,7 @@ import eu.crushedpixel.replaymod.chat.ChatMessageHandler.ChatMessageType; import eu.crushedpixel.replaymod.holders.AdvancedPosition; import eu.crushedpixel.replaymod.holders.Keyframe; import eu.crushedpixel.replaymod.holders.TimestampValue; -import eu.crushedpixel.replaymod.interpolation.AdvancedPositionLinearInterpolation; -import eu.crushedpixel.replaymod.interpolation.AdvancedPositionSplineInterpolation; -import eu.crushedpixel.replaymod.interpolation.GenericLinearInterpolation; +import eu.crushedpixel.replaymod.interpolation.KeyframeList; import eu.crushedpixel.replaymod.settings.RenderOptions; import eu.crushedpixel.replaymod.timer.EnchantmentTimer; import eu.crushedpixel.replaymod.timer.ReplayTimer; @@ -32,14 +30,10 @@ public class ReplayProcess { private static boolean linear = false; - private static AdvancedPositionSplineInterpolation motionSpline = null; - private static AdvancedPositionLinearInterpolation motionLinear = null; - private static GenericLinearInterpolation timeLinear = null; + private static int initialTimestamp = 0; private static double previousReplaySpeed = 0; - private static boolean calculated = false; - @Getter private static VideoRenderer videoRenderer = null; @@ -54,10 +48,6 @@ public class ReplayProcess { private static void resetProcess() { firstTime = true; - motionSpline = null; - motionLinear = null; - timeLinear = null; - calculated = false; requestFinish = false; lastRealTime = System.currentTimeMillis(); @@ -69,7 +59,7 @@ public class ReplayProcess { EnchantmentTimer.resetRecordingTime(); } - public static void startReplayProcess(RenderOptions renderOptions) { + public static void startReplayProcess(RenderOptions renderOptions, boolean fromStart) { mc.displayGuiScreen(null); ReplayHandler.selectKeyframe(null); @@ -89,20 +79,21 @@ public class ReplayProcess { ReplayHandler.setInPath(true); ReplayMod.replaySender.setAsyncMode(false); + //default camera path, no rendering if (renderOptions == null) { - //gets first Value and sets Replay Time to it - Keyframe tf = ReplayHandler.getTimeKeyframes().first(); - if (tf != null) { - int ts = (int)tf.getValue().value; - if (ts < ReplayMod.replaySender.currentTimeStamp()) { - mc.displayGuiScreen(null); - } - ReplayMod.replaySender.sendPacketsTill(ts); + initialTimestamp = fromStart ? 0 : ReplayHandler.getRealTimelineCursor(); + lastRealReplayTime = initialTimestamp; + + int ts = ReplayHandler.getTimeKeyframes().getInterpolatedValueForTimestamp(initialTimestamp, true).asInt(); + if (ts < ReplayMod.replaySender.currentTimeStamp()) { + mc.displayGuiScreen(null); } + ReplayMod.replaySender.sendPacketsTill(ts); ReplayMod.chatMessageHandler.addLocalizedChatMessage("replaymod.chat.pathstarted", ChatMessageType.INFORMATION); mc.timer.timerSpeed = 1; } else { + initialTimestamp = 0; boolean success = false; try { isVideoRecording = true; @@ -148,11 +139,17 @@ public class ReplayProcess { //are called if the Timer speed is set to 0, leading to this method never being //called from the RenderWorldLastEvent handlers. public static void tickReplay(boolean justCheck) { + final long curTime = System.currentTimeMillis(); + KeyframeList positionKeyframes = ReplayHandler.getPositionKeyframes(); + KeyframeList timeKeyframes = ReplayHandler.getTimeKeyframes(); + + int curRealReplayTime; + if (isVideoRecording) { return; } if(ReplayMod.replaySender.isHurrying()) { - lastRealTime = System.currentTimeMillis(); + lastRealTime = curTime; return; } @@ -161,55 +158,23 @@ public class ReplayProcess { return; } - lastRealTime = System.currentTimeMillis(); - lastRealReplayTime = 0; + lastRealTime = curTime; firstTime = false; mc.timer.renderPartialTicks = 100; mc.timer.elapsedPartialTicks = 100; mc.timer.elapsedTicks = 100; + + curRealReplayTime = lastRealReplayTime = initialTimestamp; + } else { + long timeStep = curTime - lastRealTime; + curRealReplayTime = (int) (lastRealReplayTime + timeStep); } if(justCheck) return; - int posCount = ReplayHandler.getPositionKeyframes().size(); - int timeCount = ReplayHandler.getTimeKeyframes().size(); - - if(!linear && motionSpline == null) { - //set up spline path - motionSpline = new AdvancedPositionSplineInterpolation(); - for(Keyframe kf : ReplayHandler.getPositionKeyframes()) { - motionSpline.addPoint(kf.getValue()); - } - } - - if(linear && motionLinear == null) { - //set up linear path - motionLinear = new AdvancedPositionLinearInterpolation(); - for(Keyframe kf : ReplayHandler.getPositionKeyframes()) { - motionLinear.addPoint(kf.getValue()); - } - } - if(timeLinear == null) { - timeLinear = new GenericLinearInterpolation(); - for(Keyframe kf : ReplayHandler.getTimeKeyframes()) { - timeLinear.addPoint(kf.getValue()); - } - } - - if(!calculated) { - calculated = true; - if(posCount > 1 && motionSpline != null) - motionSpline.prepare(); - } - - long curTime = System.currentTimeMillis(); - long timeStep = curTime - lastRealTime; - - int curRealReplayTime = (int) (lastRealReplayTime + timeStep); - - Keyframe lastPos = ReplayHandler.getPositionKeyframes().getPreviousKeyframe(curRealReplayTime, true); - Keyframe nextPos = ReplayHandler.getPositionKeyframes().getNextKeyframe(curRealReplayTime, true); + Keyframe lastPos = positionKeyframes.getPreviousKeyframe(curRealReplayTime, true); + Keyframe nextPos = positionKeyframes.getNextKeyframe(curRealReplayTime, true); boolean spectating = false; @@ -224,89 +189,41 @@ public class ReplayProcess { ReplayHandler.setRealTimelineCursor(curRealReplayTime); - int lastPosStamp = 0; - int nextPosStamp = 0; + Keyframe lastTime = timeKeyframes.getPreviousKeyframe(curRealReplayTime, true); + Keyframe nextTime = timeKeyframes.getNextKeyframe(curRealReplayTime, true); - if(nextPos != null || lastPos != null) { - if(nextPos != null) { - nextPosStamp = nextPos.getRealTimestamp(); - } else { - nextPosStamp = lastPos.getRealTimestamp(); - } - - if(lastPos != null) { - lastPosStamp = lastPos.getRealTimestamp(); - } else { - lastPosStamp = nextPos.getRealTimestamp(); - } - } - - Keyframe lastTime = ReplayHandler.getTimeKeyframes().getPreviousKeyframe(curRealReplayTime, true); - Keyframe nextTime = ReplayHandler.getTimeKeyframes().getNextKeyframe(curRealReplayTime, true); - - int lastTimeStamp = 0; - int nextTimeStamp = 0; + int lastTimeStamp; + int nextTimeStamp; double curSpeed = 0; - if(timeCount > 1 && (nextTime != null || lastTime != null)) { - - if(nextTime != null && lastTime != null && nextTime.getRealTimestamp() == lastTime.getRealTimestamp()) { - curSpeed = 0; + if(nextTime != null && lastTime != null && nextTime.getRealTimestamp() == lastTime.getRealTimestamp()) { + curSpeed = 0; + } else { + if(nextTime != null) { + nextTimeStamp = nextTime.getRealTimestamp(); } else { - if(nextTime != null) { - nextTimeStamp = nextTime.getRealTimestamp(); - } else { - nextTimeStamp = lastTime.getRealTimestamp(); - } + nextTimeStamp = lastTime.getRealTimestamp(); + } - if(lastTime != null) { - lastTimeStamp = lastTime.getRealTimestamp(); - } else { - lastTimeStamp = nextTime.getRealTimestamp(); - } + if(lastTime != null) { + lastTimeStamp = lastTime.getRealTimestamp(); + } else { + lastTimeStamp = nextTime.getRealTimestamp(); + } - if(!(nextTime == null || lastTime == null)) { - curSpeed = ((double) (((int)nextTime.getValue().value - (int)lastTime.getValue().value))) / ((double) ((nextTimeStamp - lastTimeStamp))); - } + if(!(nextTime == null || lastTime == null)) { + curSpeed = ((double) (((int)nextTime.getValue().value - (int)lastTime.getValue().value))) / ((double) ((nextTimeStamp - lastTimeStamp))); + } - if(lastTimeStamp == nextTimeStamp) { - curSpeed = 0f; - } + if(lastTimeStamp == nextTimeStamp) { + curSpeed = 0f; } } - int currentPosDiff = nextPosStamp - lastPosStamp; - int currentPos = curRealReplayTime - lastPosStamp; - - float currentPosStepPerc = (float) currentPos / (float) currentPosDiff; //The percentage of the travelled path between the current positions - if(Float.isInfinite(currentPosStepPerc)) currentPosStepPerc = 0; - - int currentTimeDiff = nextTimeStamp - lastTimeStamp; - int currentTime = curRealReplayTime - lastTimeStamp; - - float currentTimeStepPerc = (float) currentTime / (float) currentTimeDiff; //The percentage of the travelled path between the current timestamps - if(Float.isInfinite(currentTimeStepPerc)) currentTimeStepPerc = 0; - - float splinePos = ((float) ReplayHandler.getPositionKeyframes().indexOf(lastPos) + currentPosStepPerc) / (float) (posCount - 1); - float timePos = ((float) ReplayHandler.getTimeKeyframes().indexOf(lastTime) + currentTimeStepPerc) / (float) (timeCount - 1); - if(!spectating) { ReplayHandler.spectateCamera(); - AdvancedPosition pos = new AdvancedPosition(); - if(posCount > 1) { - if(!linear) { - motionSpline.applyPoint(Math.max(0, Math.min(1, splinePos)), pos); - } else { - motionLinear.applyPoint(Math.max(0, Math.min(1, splinePos)), pos); - } - } else { - if(posCount == 1) { - Keyframe keyframe = ReplayHandler.getPositionKeyframes().first(); - assert keyframe != null; - pos = keyframe.getValue(); - } - } + AdvancedPosition pos = positionKeyframes.getInterpolatedValueForTimestamp(curRealReplayTime, linear); if(pos != null) { ReplayHandler.setCameraTilt((float)pos.getRoll()); @@ -316,17 +233,11 @@ public class ReplayProcess { ReplayHandler.spectateEntity(mc.theWorld.getEntityByID(lastPos.getValue().getSpectatedEntityID())); } - Integer curTimestamp = null; - if(timeLinear != null && timeCount > 1) { - TimestampValue timestampValue = new TimestampValue(); - timeLinear.applyPoint(Math.max(0, Math.min(1, timePos)), timestampValue); - curTimestamp = (int) timestampValue.value; - } + Integer curTimestamp = timeKeyframes.getInterpolatedValueForTimestamp(curRealReplayTime, true).asInt(); if(!isVideoRecording()) ReplayMod.replaySender.setReplaySpeed(curSpeed); - if(curTimestamp != null) - ReplayMod.replaySender.sendPacketsTill(curTimestamp); + ReplayMod.replaySender.sendPacketsTill(curTimestamp); lastRealReplayTime = curRealReplayTime; lastRealTime = curTime; @@ -336,7 +247,8 @@ public class ReplayProcess { requestFinish = false; } - if((splinePos >= 1 || posCount <= 1) && (timePos >= 1 || timeCount <= 1)) { + if(curRealReplayTime > timeKeyframes.last().getRealTimestamp() + && curRealReplayTime > positionKeyframes.last().getRealTimestamp()) { requestFinish = true; } }