diff --git a/src/main/java/com/replaymod/pathing/properties/LensProperties.java b/src/main/java/com/replaymod/pathing/properties/LensProperties.java index 7800d7ac..6a96f748 100644 --- a/src/main/java/com/replaymod/pathing/properties/LensProperties.java +++ b/src/main/java/com/replaymod/pathing/properties/LensProperties.java @@ -13,9 +13,11 @@ import java.util.Collection; import java.util.Collections; public class LensProperties extends AbstractProperty> { + public static final float DEFAULT_FOCAL_DISTANCE = 5.0f; + public static final float DEFAULT_APERTURE_RADIUS = 0.05f; - public static final LensProperties FOCAL_DISTANCE = new LensProperties("focalDistance", 5.0f); - public static final LensProperties APERTURE_RADIUS = new LensProperties("apertureRadius", 0.05f); + public static final LensProperties FOCAL_DISTANCE = new LensProperties("focalDistance", DEFAULT_FOCAL_DISTANCE); + public static final LensProperties APERTURE_RADIUS = new LensProperties("apertureRadius", DEFAULT_APERTURE_RADIUS); public final PropertyPart> VALUE = new PropertyParts.ForFloatTriple(this, true, PropertyParts.TripleElement.LEFT); diff --git a/src/main/java/com/replaymod/render/capturer/RealLensOpenGlFrameCapturer.java b/src/main/java/com/replaymod/render/capturer/RealLensOpenGlFrameCapturer.java index 19e1145d..8c56b366 100644 --- a/src/main/java/com/replaymod/render/capturer/RealLensOpenGlFrameCapturer.java +++ b/src/main/java/com/replaymod/render/capturer/RealLensOpenGlFrameCapturer.java @@ -13,6 +13,8 @@ import org.apache.commons.lang3.tuple.Triple; import java.util.Collections; import java.util.Map; +import java.util.concurrent.ThreadLocalRandom; + public class RealLensOpenGlFrameCapturer extends OpenGlFrameCapturer { @@ -37,12 +39,14 @@ public class RealLensOpenGlFrameCapturer final float GOLDEN_ANGLE = (float) (Math.PI * (3.0 - Math.sqrt(5.0))); + float random_offset = (float) Math.sqrt(r*r/n) * 0.5f; + for (int i = 0; i < n; i++) { float rr = r * (float) Math.sqrt((float) i / n); float t = i * GOLDEN_ANGLE; points[i] = new Data( - rr * (float) Math.cos(t), - rr * (float) Math.sin(t), + rr * (float) Math.cos(t) + (ThreadLocalRandom.current().nextFloat() * 2f - 1f) * random_offset, + rr * (float) Math.sin(t) + (ThreadLocalRandom.current().nextFloat() * 2f - 1f) * random_offset, 0f, 0f, 0f ); } diff --git a/src/main/java/com/replaymod/simplepathing/SPTimeline.java b/src/main/java/com/replaymod/simplepathing/SPTimeline.java index 20e46799..26885e3a 100644 --- a/src/main/java/com/replaymod/simplepathing/SPTimeline.java +++ b/src/main/java/com/replaymod/simplepathing/SPTimeline.java @@ -159,12 +159,6 @@ public class SPTimeline implements PathingRegistry { public void addPositionKeyframe(long time, double posX, double posY, double posZ, float yaw, float pitch, float roll, int spectated) { - addPositionKeyframe(time, posX, posY, posZ, yaw, pitch, roll, spectated, 5.0f, 0.05f); - } - - public void addPositionKeyframe(long time, double posX, double posY, double posZ, - float yaw, float pitch, float roll, int spectated, - float focalDistance, float apertureRadius) { LOGGER.debug("Adding position keyframe at {} pos {}/{}/{} rot {}/{}/{} entId {}", time, posX, posY, posZ, yaw, pitch, roll, spectated); @@ -179,8 +173,8 @@ public class SPTimeline implements PathingRegistry { UpdateKeyframeProperties.Builder builder = UpdateKeyframeProperties.create(path, keyframe); builder.setValue(CameraProperties.POSITION, Triple.of(posX, posY, posZ)); builder.setValue(CameraProperties.ROTATION, Triple.of(yaw, pitch, roll)); - builder.setValue(LensProperties.FOCAL_DISTANCE, Triple.of(focalDistance, 0f, 0f)); - builder.setValue(LensProperties.APERTURE_RADIUS, Triple.of(apertureRadius, 0f, 0f)); + builder.setValue(LensProperties.FOCAL_DISTANCE, Triple.of(LensProperties.DEFAULT_FOCAL_DISTANCE, 0f, 0f)); + builder.setValue(LensProperties.APERTURE_RADIUS, Triple.of(LensProperties.DEFAULT_APERTURE_RADIUS, 0f, 0f)); if (spectated != -1) { builder.setValue(SpectatorProperty.PROPERTY, spectated); } @@ -210,13 +204,7 @@ public class SPTimeline implements PathingRegistry { } public Change updatePositionKeyframe(long time, double posX, double posY, double posZ, - float yaw, float pitch, float roll) { - return updatePositionKeyframe(time, posX, posY, posZ, yaw, pitch, roll, 5.0f, 0.05f); - } - - public Change updatePositionKeyframe(long time, double posX, double posY, double posZ, - float yaw, float pitch, float roll, - float focalDistance, float apertureRadius) { + float yaw, float pitch, float roll) { LOGGER.debug("Updating position keyframe at {} to pos {}/{}/{} rot {}/{}/{}", time, posX, posY, posZ, yaw, pitch, roll); @@ -228,8 +216,6 @@ public class SPTimeline implements PathingRegistry { Change change = UpdateKeyframeProperties.create(positionPath, keyframe) .setValue(CameraProperties.POSITION, Triple.of(posX, posY, posZ)) .setValue(CameraProperties.ROTATION, Triple.of(yaw, pitch, roll)) - .setValue(LensProperties.FOCAL_DISTANCE, Triple.of(focalDistance, 0f, 0f)) - .setValue(LensProperties.APERTURE_RADIUS, Triple.of(apertureRadius, 0f, 0f)) .done(); change.apply(timeline); return change; @@ -324,6 +310,18 @@ public class SPTimeline implements PathingRegistry { timeline.pushChange(change); } + public Change updateLensProperties(long time, float focalDistance, float apertureRadius) { + Keyframe keyframe = positionPath.getKeyframe(time); + Preconditions.checkState(keyframe != null, "Keyframe does not exist"); + + Change change = UpdateKeyframeProperties.create(positionPath, keyframe) + .setValue(LensProperties.FOCAL_DISTANCE, Triple.of(focalDistance, 0f, 0f)) + .setValue(LensProperties.APERTURE_RADIUS, Triple.of(apertureRadius, 0f, 0f)) + .done(); + change.apply(timeline); + return change; + } + public Change setInterpolatorToDefault(long time) { LOGGER.debug("Setting interpolator of position keyframe at {} to the default", time); @@ -468,6 +466,8 @@ public class SPTimeline implements PathingRegistry { // otherwise create a new interpolator interpolator = new LinearInterpolator(); interpolator.registerProperty(SpectatorProperty.PROPERTY); + interpolator.registerProperty(LensProperties.FOCAL_DISTANCE); + interpolator.registerProperty(LensProperties.APERTURE_RADIUS); } // Now that we have an interpolator, set it for the current segment updates.put(segment, interpolator); @@ -610,9 +610,9 @@ public class SPTimeline implements PathingRegistry { timeline.registerProperty(CameraProperties.POSITION); timeline.registerProperty(CameraProperties.ROTATION); timeline.registerProperty(SpectatorProperty.PROPERTY); - timeline.registerProperty(ExplicitInterpolationProperty.PROPERTY); timeline.registerProperty(LensProperties.FOCAL_DISTANCE); timeline.registerProperty(LensProperties.APERTURE_RADIUS); + timeline.registerProperty(ExplicitInterpolationProperty.PROPERTY); return timeline; } diff --git a/src/main/java/com/replaymod/simplepathing/gui/GuiEditKeyframe.java b/src/main/java/com/replaymod/simplepathing/gui/GuiEditKeyframe.java index 7f94b92b..2a32cd41 100644 --- a/src/main/java/com/replaymod/simplepathing/gui/GuiEditKeyframe.java +++ b/src/main/java/com/replaymod/simplepathing/gui/GuiEditKeyframe.java @@ -2,7 +2,6 @@ package com.replaymod.simplepathing.gui; import com.replaymod.pathing.properties.CameraProperties; import com.replaymod.pathing.properties.TimestampProperty; -import com.replaymod.pathing.properties.LensProperties; import com.replaymod.replay.ReplayModReplay; import com.replaymod.replaystudio.pathing.change.Change; import com.replaymod.replaystudio.pathing.change.CombinedChange; @@ -146,17 +145,21 @@ public abstract class GuiEditKeyframe> extends Abst protected abstract Change save(); public static class Spectator extends GuiEditKeyframe { + public final GuiLensKeyframePanel lensPanel = new GuiLensKeyframePanel(); + public Spectator(GuiPathing gui, SPPath path, long keyframe) { super(gui, path, keyframe, "spec"); - link(timeMinField, timeSecField, timeMSecField); + inputs.setLayout(new VerticalLayout().setSpacing(10)).addElements(new VerticalLayout.Data(0.5, false), lensPanel.load(this.keyframe)); + + link(lensPanel.focalDistanceField, lensPanel.apertureRadiusField, timeMinField, timeSecField, timeMSecField); popup.invokeAll(IGuiLabel.class, e -> e.setColor(Colors.BLACK)); } @Override protected Change save() { - return CombinedChange.createFromApplied(); + return guiPathing.getMod().getCurrentTimeline().updateLensProperties(time, lensPanel.getFocalDistance(), lensPanel.getApertureRadius()); } @Override @@ -215,11 +218,10 @@ public abstract class GuiEditKeyframe> extends Abst public final GuiNumberField pitchField = newGuiNumberField().setSize(60, 20).setPrecision(5); public final GuiNumberField rollField = newGuiNumberField().setSize(60, 20).setPrecision(5); - public final GuiNumberField focalDistanceField = newGuiNumberField().setSize(60, 20).setPrecision(3); - public final GuiNumberField apertureRadiusField = newGuiNumberField().setSize(60, 20).setPrecision(4); - public final InterpolationPanel interpolationPanel = new InterpolationPanel(); + public final GuiLensKeyframePanel lensPanel = new GuiLensKeyframePanel(); + { GuiPanel positionInputs = new GuiPanel() .setLayout(new GridLayout().setCellsEqualSize(false).setColumns(4).setSpacingX(3).setSpacingY(5)) @@ -229,13 +231,11 @@ public abstract class GuiEditKeyframe> extends Abst new GuiLabel().setI18nText("replaymod.gui.editkeyframe.ypos"), yField, new GuiLabel().setI18nText("replaymod.gui.editkeyframe.campitch"), pitchField, new GuiLabel().setI18nText("replaymod.gui.editkeyframe.zpos"), zField, - new GuiLabel().setI18nText("replaymod.gui.editkeyframe.camroll"), rollField, - new GuiLabel().setI18nText("replaymod.gui.editkeyframe.focalDistance"), focalDistanceField, - new GuiLabel().setI18nText("replaymod.gui.editkeyframe.apertureRadius"), apertureRadiusField + new GuiLabel().setI18nText("replaymod.gui.editkeyframe.camroll"), rollField ); inputs.setLayout(new VerticalLayout().setSpacing(10)).addElements(new VerticalLayout.Data(0.5, false), - positionInputs, interpolationPanel); + positionInputs, lensPanel, interpolationPanel); } public Position(GuiPathing gui, SPPath path, long keyframe) { @@ -252,12 +252,9 @@ public abstract class GuiEditKeyframe> extends Abst rollField.setValue(rot.getRight()); }); - this.keyframe.getValue(LensProperties.FOCAL_DISTANCE) - .ifPresent(v -> focalDistanceField.setValue(v.getLeft())); - this.keyframe.getValue(LensProperties.APERTURE_RADIUS) - .ifPresent(v -> apertureRadiusField.setValue(v.getLeft())); + lensPanel.load(this.keyframe); - link(xField, yField, zField, yawField, pitchField, rollField, focalDistanceField, apertureRadiusField, timeMinField, timeSecField, timeMSecField); + link(xField, yField, zField, yawField, pitchField, rollField, timeMinField, lensPanel.focalDistanceField, lensPanel.apertureRadiusField, timeSecField, timeMSecField); popup.invokeAll(IGuiLabel.class, e -> e.setColor(Colors.BLACK)); } @@ -267,19 +264,21 @@ public abstract class GuiEditKeyframe> extends Abst SPTimeline timeline = guiPathing.getMod().getCurrentTimeline(); Change positionChange = timeline.updatePositionKeyframe(time, xField.getDouble(), yField.getDouble(), zField.getDouble(), - yawField.getFloat(), pitchField.getFloat(), rollField.getFloat(), - focalDistanceField.getFloat(), apertureRadiusField.getFloat() + yawField.getFloat(), pitchField.getFloat(), rollField.getFloat() ); + Change lensChange = timeline.updateLensProperties(time, + lensPanel.getFocalDistance(), lensPanel.getApertureRadius()); if (interpolationPanel.getSettingsPanel() == null) { // The last keyframe doesn't have interpolator settings because there is no segment following it - return positionChange; + return CombinedChange.createFromApplied(positionChange, lensChange); } Interpolator interpolator = interpolationPanel.getSettingsPanel().createInterpolator(); if (interpolationPanel.getInterpolatorType() == InterpolatorType.DEFAULT) { - return CombinedChange.createFromApplied(positionChange, timeline.setInterpolatorToDefault(time), - timeline.setDefaultInterpolator(interpolator)); + return CombinedChange.createFromApplied(positionChange, lensChange, + timeline.setInterpolatorToDefault(time), timeline.setDefaultInterpolator(interpolator)); } else { - return CombinedChange.createFromApplied(positionChange, timeline.setInterpolator(time, interpolator)); + return CombinedChange.createFromApplied(positionChange, lensChange, + timeline.setInterpolator(time, interpolator)); } } diff --git a/src/main/java/com/replaymod/simplepathing/gui/GuiLensKeyframePanel.java b/src/main/java/com/replaymod/simplepathing/gui/GuiLensKeyframePanel.java new file mode 100644 index 00000000..44335e1f --- /dev/null +++ b/src/main/java/com/replaymod/simplepathing/gui/GuiLensKeyframePanel.java @@ -0,0 +1,37 @@ +package com.replaymod.simplepathing.gui; + +import com.replaymod.pathing.properties.LensProperties; +import com.replaymod.replaystudio.pathing.path.Keyframe; +import de.johni0702.minecraft.gui.container.AbstractGuiContainer; +import de.johni0702.minecraft.gui.element.GuiLabel; +import de.johni0702.minecraft.gui.element.GuiNumberField; +import de.johni0702.minecraft.gui.layout.GridLayout; +import org.apache.commons.lang3.tuple.Triple; + +public class GuiLensKeyframePanel extends AbstractGuiContainer { + public final GuiNumberField focalDistanceField = + new GuiNumberField().setValidateOnFocusChange(true).setSize(60, 20).setPrecision(3).setMinValue(0); + public final GuiNumberField apertureRadiusField = + new GuiNumberField().setValidateOnFocusChange(true).setSize(60, 20).setPrecision(4).setMinValue(0); + + public GuiLensKeyframePanel() { + setLayout(new GridLayout().setCellsEqualSize(false).setColumns(2).setSpacingX(3).setSpacingY(5)); + addElements(new GridLayout.Data(1, 0.5), + new GuiLabel().setI18nText("replaymod.gui.editkeyframe.focalDistance"), focalDistanceField, + new GuiLabel().setI18nText("replaymod.gui.editkeyframe.apertureRadius"), apertureRadiusField); + } + + public GuiLensKeyframePanel load(Keyframe keyframe) { + focalDistanceField.setValue(keyframe.getValue(LensProperties.FOCAL_DISTANCE) + .map(Triple::getLeft).orElse(LensProperties.DEFAULT_FOCAL_DISTANCE)); + apertureRadiusField.setValue(keyframe.getValue(LensProperties.APERTURE_RADIUS) + .map(Triple::getLeft).orElse(LensProperties.DEFAULT_APERTURE_RADIUS)); + return this; + } + + public float getFocalDistance() { return focalDistanceField.getFloat(); } + public float getApertureRadius() { return apertureRadiusField.getFloat(); } + + @Override + protected GuiLensKeyframePanel getThis() { return this; } +} \ No newline at end of file diff --git a/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java b/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java index cfa16bc7..560d5d4b 100644 --- a/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java +++ b/src/main/java/com/replaymod/simplepathing/gui/GuiPathing.java @@ -13,7 +13,6 @@ import com.replaymod.pathing.player.RealtimeTimelinePlayer; import com.replaymod.pathing.properties.CameraProperties; import com.replaymod.pathing.properties.SpectatorProperty; import com.replaymod.pathing.properties.TimestampProperty; -import com.replaymod.pathing.properties.LensProperties; import com.replaymod.render.gui.GuiRenderQueue; import com.replaymod.render.gui.GuiRenderSettings; import com.replaymod.replay.ReplayHandler; @@ -54,7 +53,6 @@ import net.minecraft.client.resource.language.I18n; import net.minecraft.util.crash.CrashReport; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.commons.lang3.tuple.Triple; //#if MC>=11400 //#else @@ -705,14 +703,8 @@ public class GuiPathing { if (!replayHandler.isCameraView() && !neverSpectator) { spectatedId = replayHandler.getOverlay().getMinecraft().getCameraEntity().getEntityId(); } - - float focalDistance = timeline.getPositionPath() - .getValue(LensProperties.FOCAL_DISTANCE, time).map(Triple::getLeft).orElse(5.0f); - float apertureRadius = timeline.getPositionPath() - .getValue(LensProperties.APERTURE_RADIUS, time).map(Triple::getLeft).orElse(0.05f); - timeline.addPositionKeyframe(time, camera.getX(), camera.getY(), camera.getZ(), - camera.yaw, camera.pitch, camera.roll, spectatedId, focalDistance, apertureRadius); + camera.yaw, camera.pitch, camera.roll, spectatedId); mod.setSelected(path, time); } break;