Implemented/fixed Time Keyframes

Some optimization to follow!
This commit is contained in:
Marius Metzger
2015-01-13 15:01:03 +01:00
parent 25c4f85a4c
commit 1afdd6df2b
4 changed files with 67 additions and 45 deletions

View File

@@ -50,8 +50,6 @@ public class GuiReplayOverlay extends Gui {
private int realTimelineX = 10 + 3*25; private int realTimelineX = 10 + 3*25;
private int realTimelineY = 33+10; private int realTimelineY = 33+10;
private int realTimePosition = 0;
private int ppButtonX = 10; private int ppButtonX = 10;
private int ppButtonY = 10; private int ppButtonY = 10;
@@ -110,7 +108,7 @@ public class GuiReplayOverlay extends Gui {
if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { if(FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) {
mc.displayGuiScreen((GuiScreen)null); mc.displayGuiScreen((GuiScreen)null);
} }
realTimePosition = 0; ReplayHandler.setRealTimelineCursor(0);
speedSlider = new GuiReplaySpeedSlider(1, sliderX, sliderY, "Speed"); speedSlider = new GuiReplaySpeedSlider(1, sliderX, sliderY, "Speed");
} }
@@ -163,7 +161,8 @@ public class GuiReplayOverlay extends Gui {
//GlStateManager.resetColor(); //GlStateManager.resetColor();
if(Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class)) { //clicking the Button //When hurrying, no Timeline jumping etc. is possible
if(Mouse.isButtonDown(0) && FMLClientHandler.instance().isGUIOpen(GuiMouseInput.class) && !ReplayHandler.isHurrying()) { //clicking the Button
speedSlider.mousePressed(mc, mouseX, mouseY); speedSlider.mousePressed(mc, mouseX, mouseY);
if(!mouseDown) { if(!mouseDown) {
mouseDown = true; mouseDown = true;
@@ -543,7 +542,7 @@ public class GuiReplayOverlay extends Gui {
float abs_width = (zoom_scale*(float)timelineLength); float abs_width = (zoom_scale*(float)timelineLength);
int real_pos = Math.round(left_real+((rel_pos)*abs_width)); int real_pos = Math.round(left_real+((rel_pos)*abs_width));
realTimePosition = real_pos; ReplayHandler.setRealTimelineCursor(real_pos);
//Keyframe click handling here //Keyframe click handling here
if(isClick()) { if(isClick()) {
@@ -551,18 +550,18 @@ public class GuiReplayOverlay extends Gui {
int tolerance = 2*Math.round(abs_width/(float)width); int tolerance = 2*Math.round(abs_width/(float)width);
if(mouseY >= y+9) { if(mouseY >= y+9) {
TimeKeyframe close = ReplayHandler.getClosestTimeKeyframeForRealTime(realTimePosition, tolerance); TimeKeyframe close = ReplayHandler.getClosestTimeKeyframeForRealTime(ReplayHandler.getRealTimelineCursor(), tolerance);
ReplayHandler.selectKeyframe(close); //can be null, deselects keyframe ReplayHandler.selectKeyframe(close); //can be null, deselects keyframe
} else { } else {
PositionKeyframe close = ReplayHandler.getClosestPlaceKeyframeForRealTime(realTimePosition, tolerance); PositionKeyframe close = ReplayHandler.getClosestPlaceKeyframeForRealTime(ReplayHandler.getRealTimelineCursor(), tolerance);
ReplayHandler.selectKeyframe(close); //can be null, deselects keyframe ReplayHandler.selectKeyframe(close); //can be null, deselects keyframe
} }
} }
} }
//Draw Realtime Cursor //Draw Realtime Cursor
if(realTimePosition >= left_real && realTimePosition <= right_real) { if(ReplayHandler.getRealTimelineCursor() >= left_real && ReplayHandler.getRealTimelineCursor() <= right_real) {
long rel_pos = realTimePosition-left_real; long rel_pos = ReplayHandler.getRealTimelineCursor()-left_real;
long rel_width = right_real-left_real; long rel_width = right_real-left_real;
double perc = (double)rel_pos/(double)rel_width; double perc = (double)rel_pos/(double)rel_width;
@@ -650,11 +649,11 @@ public class GuiReplayOverlay extends Gui {
private void addPlaceKeyframe() { private void addPlaceKeyframe() {
CameraEntity cam = ReplayHandler.getCameraEntity(); CameraEntity cam = ReplayHandler.getCameraEntity();
if(cam == null) return; if(cam == null) return;
ReplayHandler.addKeyframe(new PositionKeyframe(realTimePosition, new Position(cam.posX, cam.posY, cam.posZ, cam.rotationPitch, cam.rotationYaw))); ReplayHandler.addKeyframe(new PositionKeyframe(ReplayHandler.getRealTimelineCursor(), new Position(cam.posX, cam.posY, cam.posZ, cam.rotationPitch, cam.rotationYaw)));
} }
private void addTimeKeyframe() { private void addTimeKeyframe() {
ReplayHandler.addKeyframe(new TimeKeyframe(realTimePosition, ReplayHandler.getReplayTime())); ReplayHandler.addKeyframe(new TimeKeyframe(ReplayHandler.getRealTimelineCursor(), ReplayHandler.getReplayTime()));
} }
private enum MarkerType { private enum MarkerType {

View File

@@ -33,6 +33,8 @@ public class ReplayHandler {
private static ReplaySender replaySender; private static ReplaySender replaySender;
private static OpenEmbeddedChannel channel; private static OpenEmbeddedChannel channel;
private static int realTimelinePosition = 0;
private static Keyframe selectedKeyframe; private static Keyframe selectedKeyframe;
private static boolean isReplaying = false; private static boolean isReplaying = false;
@@ -232,7 +234,13 @@ public class ReplayHandler {
public static void setReplayPos(int pos) { public static void setReplayPos(int pos) {
if(replaySender != null) { if(replaySender != null) {
replaySender.jumpToTime(pos); replaySender.jumpToTime(pos, false);
}
}
public static void forceReplayPos(int pos) {
if(replaySender != null) {
replaySender.jumpToTime(pos, true);
} }
} }
@@ -358,4 +366,12 @@ public class ReplayHandler {
public static Keyframe getSelected() { public static Keyframe getSelected() {
return selectedKeyframe; return selectedKeyframe;
} }
public static int getRealTimelineCursor() {
return realTimelinePosition;
}
public static void setRealTimelineCursor(int pos) {
realTimelinePosition = pos;
}
} }

View File

@@ -1,6 +1,7 @@
package eu.crushedpixel.replaymod.replay; package eu.crushedpixel.replaymod.replay;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import eu.crushedpixel.replaymod.ReplayMod; import eu.crushedpixel.replaymod.ReplayMod;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests; import eu.crushedpixel.replaymod.chat.ChatMessageRequests;
import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType; import eu.crushedpixel.replaymod.chat.ChatMessageRequests.ChatMessageType;
@@ -48,13 +49,16 @@ public class ReplayProcess {
ReplayHandler.sortKeyframes(); ReplayHandler.sortKeyframes();
ReplayHandler.setReplaying(true); ReplayHandler.setReplaying(true);
previousReplaySpeed = ReplayHandler.getSpeed(); previousReplaySpeed = ReplayHandler.getSpeed();
/*
TimeKeyframe tf = ReplayHandler.getNextTimeKeyframe(-1); TimeKeyframe tf = ReplayHandler.getNextTimeKeyframe(-1);
if(tf != null) { if(tf != null) {
int ts = tf.getTimestamp(); int ts = tf.getTimestamp();
ReplayHandler.setReplayPos(ts); if(ts < ReplayHandler.getReplayTime()) {
mc.displayGuiScreen((GuiScreen)null);
}
ReplayHandler.forceReplayPos(ts);
} }
*/
ChatMessageRequests.addChatMessage("Replay started!", ChatMessageType.INFORMATION); ChatMessageRequests.addChatMessage("Replay started!", ChatMessageType.INFORMATION);
} }
@@ -65,13 +69,10 @@ public class ReplayProcess {
ReplayHandler.setSpeed(previousReplaySpeed); ReplayHandler.setSpeed(previousReplaySpeed);
ReplayHandler.setSpeed(0); ReplayHandler.setSpeed(0);
} }
public static void tickReplay() { public static void tickReplay() {
if(!ReplayHandler.isReplaying()) return;
if(ReplayHandler.isHurrying()) { if(ReplayHandler.isHurrying()) {
lastRealTime = System.currentTimeMillis(); lastRealTime = System.currentTimeMillis();
System.out.println("rethurrn");
return; return;
} }
@@ -113,8 +114,9 @@ public class ReplayProcess {
//timeLinear.getPoint(x); //timeLinear.getPoint(x);
System.out.println(x+" | "+timeLinear.getPoint(x)); System.out.println(x+" | "+timeLinear.getPoint(x));
} }
*/ */
//System.out.println(timeLinear.getPoint(0)); //System.out.println(timeLinear.getPoint(0));
} }
long curTime = System.currentTimeMillis(); long curTime = System.currentTimeMillis();
@@ -125,6 +127,8 @@ public class ReplayProcess {
PositionKeyframe lastPos = ReplayHandler.getPreviousPositionKeyframe(curRealReplayTime); PositionKeyframe lastPos = ReplayHandler.getPreviousPositionKeyframe(curRealReplayTime);
PositionKeyframe nextPos = ReplayHandler.getNextPositionKeyframe(curRealReplayTime); PositionKeyframe nextPos = ReplayHandler.getNextPositionKeyframe(curRealReplayTime);
ReplayHandler.setRealTimelineCursor(curRealReplayTime);
int lastPosStamp = 0; int lastPosStamp = 0;
int nextPosStamp = 0; int nextPosStamp = 0;
@@ -176,23 +180,23 @@ public class ReplayProcess {
float splinePos = ((float)ReplayHandler.getKeyframeIndex(lastPos) + currentStepPerc)/(float)(ReplayHandler.getPosKeyframeCount()-1); float splinePos = ((float)ReplayHandler.getKeyframeIndex(lastPos) + currentStepPerc)/(float)(ReplayHandler.getPosKeyframeCount()-1);
float timePos = ((float)ReplayHandler.getKeyframeIndex(lastTime) + currentStepPerc)/(float)(ReplayHandler.getTimeKeyframeCount()-1); float timePos = ((float)ReplayHandler.getKeyframeIndex(lastTime) + currentStepPerc)/(float)(ReplayHandler.getTimeKeyframeCount()-1);
Position pos = null; Position pos = null;
if(!linear) { if(!linear) {
pos = motionSpline.getPoint(Math.max(0, Math.min(1, splinePos))); pos = motionSpline.getPoint(Math.max(0, Math.min(1, splinePos)));
} else { } else {
pos = motionLinear.getPoint(Math.max(0, Math.min(1, splinePos))); pos = motionLinear.getPoint(Math.max(0, Math.min(1, splinePos)));
} }
//int curPos = timeLinear.getPoint(Math.max(0, Math.min(1, timePos))); int curPos = timeLinear.getPoint(Math.max(0, Math.min(1, timePos)));
//set replay speed //set replay speed
if(pos != null) ReplayHandler.getCameraEntity().movePath(pos); if(pos != null) ReplayHandler.getCameraEntity().movePath(pos);
//System.out.println(curSpeed+" | "+curPos); //System.out.println(curSpeed+" | "+curPos);
//ReplayHandler.setSpeed(curSpeed); ReplayHandler.setSpeed(curSpeed);
//System.out.println("sent "+curPos); //System.out.println("sent "+curPos);
//ReplayHandler.setReplayPos(curPos, timePos == 0); ReplayHandler.setReplayPos(curPos);
//calculate replay speed //calculate replay speed
@@ -201,11 +205,11 @@ public class ReplayProcess {
if(ts != lastTimestamp) { if(ts != lastTimestamp) {
lastTimestamp = ts; lastTimestamp = ts;
} }
*/ */
//splinePos = (index of last entry + add) / total entries //splinePos = (index of last entry + add) / total entries
lastRealReplayTime = curRealReplayTime; lastRealReplayTime = curRealReplayTime;
lastRealTime = curTime; lastRealTime = curTime;

View File

@@ -89,9 +89,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
private float defaultReplaySpeed = 0.5f; private float defaultReplaySpeed = 0.5f;
private int packetAt = 0;
private double replaySpeed = 1f; private double replaySpeed = 1f;
private long lastTime = 0, lastTimestamp = 0;
private Field joinPacketEntityId, joinPacketWorldType, private Field joinPacketEntityId, joinPacketWorldType,
joinPacketDimension, joinPacketDifficulty, joinPacketMaxPlayers; joinPacketDimension, joinPacketDifficulty, joinPacketMaxPlayers;
@@ -137,15 +135,18 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
} }
} }
public void jumpToTime(int millis) { public void jumpToTime(int millis, boolean force) {
setReplaySpeed(replaySpeed); setReplaySpeed(replaySpeed);
if((millis < currentTimeStamp && !isHurrying())) { if((millis < currentTimeStamp && !isHurrying())) {
startFromBeginning = true; if(!(ReplayHandler.isReplaying() && !force)) {
startFromBeginning = true;
}
} }
desiredTimeStamp = millis; desiredTimeStamp = millis;
hurryToTimestamp = true; hurryToTimestamp = true;
} }
public void setReplaySpeed(final double d) { public void setReplaySpeed(final double d) {
@@ -244,8 +245,10 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
while(!terminate) { while(!terminate) {
if(startFromBeginning) { if(startFromBeginning) {
currentTimeStamp = 0; currentTimeStamp = 0;
dis.close();
dis = new DataInputStream(archive.getInputStream(replayEntry)); dis = new DataInputStream(archive.getInputStream(replayEntry));
startFromBeginning = false; startFromBeginning = false;
lastPacketSent = System.currentTimeMillis();
ReplayHandler.restartReplay(); ReplayHandler.restartReplay();
} }
while(!startFromBeginning && (!paused() || FMLClientHandler.instance().isGUIOpen(GuiDownloadTerrain.class))) { while(!startFromBeginning && (!paused() || FMLClientHandler.instance().isGUIOpen(GuiDownloadTerrain.class))) {
@@ -262,24 +265,22 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
* If hurrying, don't wait for correct timing. * If hurrying, don't wait for correct timing.
*/ */
/*
if(!hurryToTimestamp && ReplayHandler.isReplaying()) { if(!hurryToTimestamp && ReplayHandler.isReplaying()) {
continue; continue;
} else if(ReplayHandler.isReplaying()) {
System.out.println("nocont "+currentTimeStamp+" | "+((Timer)mcTimer.get(mc)).timerSpeed);
} }
*/
int timestamp = dis.readInt(); int timestamp = dis.readInt();
currentTimeStamp = timestamp; currentTimeStamp = timestamp;
//if(!ReplayHandler.isReplaying() && !hurryToTimestamp && !FMLClientHandler.instance().isGUIOpen(GuiDownloadTerrain.class)) { if(!ReplayHandler.isReplaying() && !hurryToTimestamp && !FMLClientHandler.instance().isGUIOpen(GuiDownloadTerrain.class)) {
if(!hurryToTimestamp && !FMLClientHandler.instance().isGUIOpen(GuiDownloadTerrain.class)) { //if(!hurryToTimestamp && !FMLClientHandler.instance().isGUIOpen(GuiDownloadTerrain.class)) {
int timeWait = (int)Math.round((currentTimeStamp - lastTimeStamp)/replaySpeed); int timeWait = (int)Math.round((currentTimeStamp - lastTimeStamp)/replaySpeed);
long timeDiff = System.currentTimeMillis() - lastPacketSent; long timeDiff = System.currentTimeMillis() - lastPacketSent;
lastPacketSent = System.currentTimeMillis(); lastPacketSent = System.currentTimeMillis();
Thread.sleep(Math.max(0, timeWait-timeDiff)); long timeToSleep = Math.max(0, timeWait-timeDiff);
Thread.sleep(timeToSleep);
} }
int bytes = dis.readInt(); int bytes = dis.readInt();
@@ -292,7 +293,9 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
if(hurryToTimestamp && currentTimeStamp >= desiredTimeStamp && !startFromBeginning) { if(hurryToTimestamp && currentTimeStamp >= desiredTimeStamp && !startFromBeginning) {
hurryToTimestamp = false; hurryToTimestamp = false;
System.out.println("stop hurrying"); if(!ReplayHandler.isReplaying()) {
setReplaySpeed(0);
}
} }
} catch(EOFException eof) { } catch(EOFException eof) {
@@ -320,7 +323,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
add(S37PacketStatistics.class); add(S37PacketStatistics.class);
} }
}; };
@Override @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) public void channelRead(ChannelHandlerContext ctx, Object msg)
throws Exception { throws Exception {
@@ -353,7 +356,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
return; return;
} }
} }
if(badPackets.contains(p.getClass())) return; if(badPackets.contains(p.getClass())) return;
try { try {
@@ -395,7 +398,7 @@ public class ReplaySender extends ChannelInboundHandlerAdapter {
if(p instanceof S08PacketPlayerPosLook) { if(p instanceof S08PacketPlayerPosLook) {
final S08PacketPlayerPosLook ppl = (S08PacketPlayerPosLook)p; final S08PacketPlayerPosLook ppl = (S08PacketPlayerPosLook)p;
if(ReplayHandler.isReplaying()) return; //if(ReplayHandler.isReplaying()) return;
Thread t = new Thread(new Runnable() { Thread t = new Thread(new Runnable() {
@Override @Override