Add Catmull-Rom spline interpolator to simplepathing
This commit is contained in:
Submodule ReplayStudio updated: a0b1f2b662...c615476693
@@ -1,5 +1,6 @@
|
|||||||
package com.replaymod.simplepathing;
|
package com.replaymod.simplepathing;
|
||||||
|
|
||||||
|
import com.replaymod.replaystudio.pathing.interpolation.CatmullRomSplineInterpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.CubicSplineInterpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.CubicSplineInterpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.Interpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.Interpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.LinearInterpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.LinearInterpolator;
|
||||||
@@ -11,6 +12,7 @@ import java.util.function.Supplier;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum InterpolatorType {
|
public enum InterpolatorType {
|
||||||
DEFAULT("default", null, null),
|
DEFAULT("default", null, null),
|
||||||
|
CATMULL_ROM("catmullrom", CatmullRomSplineInterpolator.class, () -> new CatmullRomSplineInterpolator(0.5)),
|
||||||
CUBIC("cubic", CubicSplineInterpolator.class, CubicSplineInterpolator::new),
|
CUBIC("cubic", CubicSplineInterpolator.class, CubicSplineInterpolator::new),
|
||||||
LINEAR("linear", LinearInterpolator.class, LinearInterpolator::new);
|
LINEAR("linear", LinearInterpolator.class, LinearInterpolator::new);
|
||||||
|
|
||||||
@@ -34,7 +36,7 @@ public enum InterpolatorType {
|
|||||||
for (InterpolatorType t : values()) {
|
for (InterpolatorType t : values()) {
|
||||||
if (t.getI18nName().equals(string)) return t;
|
if (t.getI18nName().equals(string)) return t;
|
||||||
}
|
}
|
||||||
return CUBIC; //the default
|
return CATMULL_ROM; //the default
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InterpolatorType fromClass(Class<? extends Interpolator> cls) {
|
public static InterpolatorType fromClass(Class<? extends Interpolator> cls) {
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ package com.replaymod.simplepathing;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
import com.google.gson.stream.JsonReader;
|
import com.google.gson.stream.JsonReader;
|
||||||
import com.google.gson.stream.JsonWriter;
|
import com.google.gson.stream.JsonWriter;
|
||||||
import com.replaymod.pathing.properties.CameraProperties;
|
import com.replaymod.pathing.properties.CameraProperties;
|
||||||
@@ -14,6 +16,7 @@ import com.replaymod.replaystudio.pathing.change.CombinedChange;
|
|||||||
import com.replaymod.replaystudio.pathing.change.SetInterpolator;
|
import com.replaymod.replaystudio.pathing.change.SetInterpolator;
|
||||||
import com.replaymod.replaystudio.pathing.change.UpdateKeyframeProperties;
|
import com.replaymod.replaystudio.pathing.change.UpdateKeyframeProperties;
|
||||||
import com.replaymod.replaystudio.pathing.impl.TimelineImpl;
|
import com.replaymod.replaystudio.pathing.impl.TimelineImpl;
|
||||||
|
import com.replaymod.replaystudio.pathing.interpolation.CatmullRomSplineInterpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.CubicSplineInterpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.CubicSplineInterpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.Interpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.Interpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.LinearInterpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.LinearInterpolator;
|
||||||
@@ -68,7 +71,7 @@ public class SPTimeline implements PathingRegistry {
|
|||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private EntityPositionTracker entityTracker;
|
private EntityPositionTracker entityTracker;
|
||||||
private InterpolatorType defaultInterpolatorType = InterpolatorType.CUBIC;
|
private InterpolatorType defaultInterpolatorType = InterpolatorType.fromString("invalid string returns default");
|
||||||
|
|
||||||
public SPTimeline() {
|
public SPTimeline() {
|
||||||
this(createInitialTimeline());
|
this(createInitialTimeline());
|
||||||
@@ -573,6 +576,11 @@ public class SPTimeline implements PathingRegistry {
|
|||||||
writer.value("linear");
|
writer.value("linear");
|
||||||
} else if (interpolator instanceof CubicSplineInterpolator) {
|
} else if (interpolator instanceof CubicSplineInterpolator) {
|
||||||
writer.value("cubic-spline");
|
writer.value("cubic-spline");
|
||||||
|
} else if (interpolator instanceof CatmullRomSplineInterpolator) {
|
||||||
|
writer.beginObject();
|
||||||
|
writer.name("type").value("catmull-rom-spline");
|
||||||
|
writer.name("alpha").value(((CatmullRomSplineInterpolator) interpolator).getAlpha());
|
||||||
|
writer.endObject();
|
||||||
} else {
|
} else {
|
||||||
throw new IOException("Unknown interpolator type: " + interpolator);
|
throw new IOException("Unknown interpolator type: " + interpolator);
|
||||||
}
|
}
|
||||||
@@ -580,12 +588,30 @@ public class SPTimeline implements PathingRegistry {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Interpolator deserializeInterpolator(JsonReader reader) throws IOException {
|
public Interpolator deserializeInterpolator(JsonReader reader) throws IOException {
|
||||||
String type = reader.nextString();
|
String type;
|
||||||
|
JsonObject args;
|
||||||
|
switch (reader.peek()) {
|
||||||
|
case STRING:
|
||||||
|
type = reader.nextString();
|
||||||
|
args = null;
|
||||||
|
break;
|
||||||
|
case BEGIN_OBJECT:
|
||||||
|
args = new JsonParser().parse(reader).getAsJsonObject();
|
||||||
|
type = args.get("type").getAsString();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IOException("Unexpected token: " + reader.peek());
|
||||||
|
}
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "linear":
|
case "linear":
|
||||||
return new LinearInterpolator();
|
return new LinearInterpolator();
|
||||||
case "cubic-spline":
|
case "cubic-spline":
|
||||||
return new CubicSplineInterpolator();
|
return new CubicSplineInterpolator();
|
||||||
|
case "catmull-rom-spline":
|
||||||
|
if (args == null || !args.has("alpha")) {
|
||||||
|
throw new IOException("Missing alpha value for catmull-rom-spline.");
|
||||||
|
}
|
||||||
|
return new CatmullRomSplineInterpolator(args.get("alpha").getAsDouble());
|
||||||
default:
|
default:
|
||||||
throw new IOException("Unknown interpolation type: " + type);
|
throw new IOException("Unknown interpolation type: " + type);
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.replaymod.pathing.properties.TimestampProperty;
|
|||||||
import com.replaymod.replay.ReplayModReplay;
|
import com.replaymod.replay.ReplayModReplay;
|
||||||
import com.replaymod.replaystudio.pathing.change.Change;
|
import com.replaymod.replaystudio.pathing.change.Change;
|
||||||
import com.replaymod.replaystudio.pathing.change.CombinedChange;
|
import com.replaymod.replaystudio.pathing.change.CombinedChange;
|
||||||
|
import com.replaymod.replaystudio.pathing.interpolation.CatmullRomSplineInterpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.CubicSplineInterpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.CubicSplineInterpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.Interpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.Interpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.LinearInterpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.LinearInterpolator;
|
||||||
@@ -317,6 +318,9 @@ public abstract class GuiEditKeyframe<T extends GuiEditKeyframe<T>> extends Abst
|
|||||||
removeElement(this.settingsPanel);
|
removeElement(this.settingsPanel);
|
||||||
|
|
||||||
switch (getInterpolatorTypeNoDefault(type)) {
|
switch (getInterpolatorTypeNoDefault(type)) {
|
||||||
|
case CATMULL_ROM:
|
||||||
|
settingsPanel = new CatmullRomSettingsPanel();
|
||||||
|
break;
|
||||||
case CUBIC:
|
case CUBIC:
|
||||||
settingsPanel = new CubicSettingsPanel();
|
settingsPanel = new CubicSettingsPanel();
|
||||||
break;
|
break;
|
||||||
@@ -353,6 +357,33 @@ public abstract class GuiEditKeyframe<T extends GuiEditKeyframe<T>> extends Abst
|
|||||||
public abstract I createInterpolator();
|
public abstract I createInterpolator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class CatmullRomSettingsPanel extends SettingsPanel<CatmullRomSplineInterpolator, CatmullRomSettingsPanel> {
|
||||||
|
public final GuiLabel alphaLabel = new GuiLabel().setColor(Colors.BLACK)
|
||||||
|
.setI18nText("replaymod.gui.editkeyframe.interpolator.catmullrom.alpha");
|
||||||
|
public final GuiNumberField alphaField = new GuiNumberField().setSize(100, 20).setPrecision(5)
|
||||||
|
.setMinValue(0).setValidateOnFocusChange(true);
|
||||||
|
|
||||||
|
{
|
||||||
|
setLayout(new HorizontalLayout(HorizontalLayout.Alignment.CENTER));
|
||||||
|
addElements(new HorizontalLayout.Data(0.5), alphaLabel, alphaField);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loadSettings(CatmullRomSplineInterpolator interpolator) {
|
||||||
|
alphaField.setValue(interpolator.getAlpha());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CatmullRomSplineInterpolator createInterpolator() {
|
||||||
|
return new CatmullRomSplineInterpolator(alphaField.getDouble());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected CatmullRomSettingsPanel getThis() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class CubicSettingsPanel extends SettingsPanel<CubicSplineInterpolator, CubicSettingsPanel> {
|
public class CubicSettingsPanel extends SettingsPanel<CubicSplineInterpolator, CubicSettingsPanel> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -292,6 +292,7 @@ replaymod.gui.settings.title=Replay Mod Settings
|
|||||||
|
|
||||||
replaymod.gui.settings.interpolation.linear=Linear
|
replaymod.gui.settings.interpolation.linear=Linear
|
||||||
replaymod.gui.settings.interpolation.cubic=Cubic
|
replaymod.gui.settings.interpolation.cubic=Cubic
|
||||||
|
replaymod.gui.settings.interpolation.catmullrom=Catmull Rom
|
||||||
|
|
||||||
replaymod.gui.settings.bitrate=Video Bitrate
|
replaymod.gui.settings.bitrate=Video Bitrate
|
||||||
replaymod.gui.settings.framerate=Video Framerate
|
replaymod.gui.settings.framerate=Video Framerate
|
||||||
@@ -376,6 +377,9 @@ replaymod.gui.editkeyframe.spec.method.shoulder.smoothness=Path Smoothness
|
|||||||
replaymod.gui.editkeyframe.interpolator=Interpolator
|
replaymod.gui.editkeyframe.interpolator=Interpolator
|
||||||
replaymod.gui.editkeyframe.interpolator.default.name=Default Interpolator
|
replaymod.gui.editkeyframe.interpolator.default.name=Default Interpolator
|
||||||
replaymod.gui.editkeyframe.interpolator.default.desc=Uses the default interpolator defined in the Replay Mod Settings.
|
replaymod.gui.editkeyframe.interpolator.default.desc=Uses the default interpolator defined in the Replay Mod Settings.
|
||||||
|
replaymod.gui.editkeyframe.interpolator.catmullrom.name=Catmull Rom Spline Interpolator
|
||||||
|
replaymod.gui.editkeyframe.interpolator.catmullrom.desc=Calculates a catmull rom spline with customizable alpha value for precise tightness and smoothness of the camera path.
|
||||||
|
replaymod.gui.editkeyframe.interpolator.catmullrom.alpha=Alpha:
|
||||||
replaymod.gui.editkeyframe.interpolator.cubic.name=Cubic Spline Interpolator
|
replaymod.gui.editkeyframe.interpolator.cubic.name=Cubic Spline Interpolator
|
||||||
replaymod.gui.editkeyframe.interpolator.cubic.desc=Calculates a cubic equation matrix for all points for a smooth camera path.
|
replaymod.gui.editkeyframe.interpolator.cubic.desc=Calculates a cubic equation matrix for all points for a smooth camera path.
|
||||||
replaymod.gui.editkeyframe.interpolator.linear.name=Linear Interpolator
|
replaymod.gui.editkeyframe.interpolator.linear.name=Linear Interpolator
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import com.replaymod.pathing.properties.CameraProperties;
|
|||||||
import com.replaymod.pathing.properties.SpectatorProperty;
|
import com.replaymod.pathing.properties.SpectatorProperty;
|
||||||
import com.replaymod.pathing.properties.TimestampProperty;
|
import com.replaymod.pathing.properties.TimestampProperty;
|
||||||
import com.replaymod.replaystudio.pathing.change.Change;
|
import com.replaymod.replaystudio.pathing.change.Change;
|
||||||
|
import com.replaymod.replaystudio.pathing.interpolation.CatmullRomSplineInterpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.Interpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.Interpolator;
|
||||||
import com.replaymod.replaystudio.pathing.interpolation.LinearInterpolator;
|
import com.replaymod.replaystudio.pathing.interpolation.LinearInterpolator;
|
||||||
import com.replaymod.replaystudio.pathing.path.Keyframe;
|
import com.replaymod.replaystudio.pathing.path.Keyframe;
|
||||||
@@ -510,6 +511,37 @@ public class SPTimelineTest {
|
|||||||
assertValidInterpolators(SPPath.POSITION, 4);
|
assertValidInterpolators(SPPath.POSITION, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException.class)
|
||||||
|
public void testSetDefaultInterpolatorDifferentType() {
|
||||||
|
addPosition(0, 0);
|
||||||
|
addPosition(1, 1);
|
||||||
|
impl.setDefaultInterpolator(new CatmullRomSplineInterpolator(42));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSetDefaultInterpolatorSameType() {
|
||||||
|
impl.setDefaultInterpolatorType(InterpolatorType.CATMULL_ROM);
|
||||||
|
addPosition(0, 0);
|
||||||
|
addSpectator(1, 1);
|
||||||
|
addSpectator(2, 2);
|
||||||
|
addPosition(3, 3);
|
||||||
|
addPosition(4, 3);
|
||||||
|
impl.setDefaultInterpolator(new CatmullRomSplineInterpolator(42));
|
||||||
|
assertValidInterpolators(SPPath.POSITION, 3);
|
||||||
|
assertIsCatmullRom(0, 42);
|
||||||
|
assertIsCatmullRom(2, 42);
|
||||||
|
assertIsCatmullRom(3, 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertIsCatmullRom(int index, double alpha) {
|
||||||
|
String str = prettyPrintInterpolators(impl, SPPath.POSITION);
|
||||||
|
Interpolator interpolator = Iterables.get(impl.getPositionPath().getSegments(), index).getInterpolator();
|
||||||
|
assertTrue("Expected segment " + index + " to be catmull rom interpolator: " + str,
|
||||||
|
interpolator instanceof CatmullRomSplineInterpolator);
|
||||||
|
assertTrue("Expected interpolator of segment segment " + index + " to have alpha " + alpha + ": " + str,
|
||||||
|
((CatmullRomSplineInterpolator) interpolator).getAlpha() == 42);
|
||||||
|
}
|
||||||
|
|
||||||
private void addPosition(int time, int expectedNumberOfInterpolators) {
|
private void addPosition(int time, int expectedNumberOfInterpolators) {
|
||||||
impl.addPositionKeyframe(time, 1, 2, 3, 4, 5, 6, -1);
|
impl.addPositionKeyframe(time, 1, 2, 3, 4, 5, 6, -1);
|
||||||
assertNotNull(impl.getKeyframe(SPPath.POSITION, time));
|
assertNotNull(impl.getKeyframe(SPPath.POSITION, time));
|
||||||
|
|||||||
Reference in New Issue
Block a user