diff --git a/src/main/java/dev/latvian/mods/kmath/util/Easing.java b/src/main/java/dev/latvian/mods/kmath/util/Easing.java
index a82ff83..fe7e9ea 100644
--- a/src/main/java/dev/latvian/mods/kmath/util/Easing.java
+++ b/src/main/java/dev/latvian/mods/kmath/util/Easing.java
@@ -4,69 +4,63 @@
import it.unimi.dsi.fastutil.doubles.Double2DoubleFunction;
import net.minecraft.util.math.Vec3d;
-@FunctionalInterface
-public interface Easing extends Double2DoubleFunction {
- double ease(double x);
-
- default double easeClamped(double x) {
- return ease(KMath.clamp(x, 0D, 1D));
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Source
+ */
+public final class Easing {
+ public static final Map FUNCTIONS = new LinkedHashMap<>();
+
+ public static Easing add(String id, Double2DoubleFunction function) {
+ var easing = add(id, function);
+ FUNCTIONS.put(id, easing);
+ return easing;
}
- @Override
- default double get(double x) {
- return ease(x);
- }
+ public static final Easing LINEAR = add("linear", x -> x);
+ public static final Easing SMOOTHSTEP = add("smoothstep", KMath::smoothstep);
+ public static final Easing ISMOOTHSTEP = add("ismoothstep", KMath::ismoothstep);
+ public static final Easing SMOOTHERSTEP = add("smootherstep", KMath::smootherstep);
- default double lerp(double t, double a, double b) {
- return a + get(t) * (b - a);
- }
-
- default Vec3d lerp(double t, Vec3d a, Vec3d b) {
- return new Vec3d(lerp(t, a.x, b.x), lerp(t, a.y, b.y), lerp(t, a.z, b.z));
- }
+ public static final Easing SINE_IN = add("sine_in", x -> 1 - Math.cos((x - Math.PI) / 2));
+ public static final Easing SINE_OUT = add("sine_out", x -> Math.sin((x * Math.PI) / 2));
+ public static final Easing SINE_IN_OUT = add("sine_in_out", x -> -(Math.cos(Math.PI * x) - 1) / 2);
- Easing LINEAR = x -> x;
- Easing SMOOTHSTEP = KMath::smoothstep;
- Easing ISMOOTHSTEP = KMath::ismoothstep;
- Easing SMOOTHERSTEP = KMath::smootherstep;
+ public static final Easing QUAD_IN = add("quad_in", x -> x * x);
+ public static final Easing QUAD_OUT = add("quad_out", x -> 1 - (1 - x) * (1 - x));
+ public static final Easing QUAD_IN_OUT = add("quad_in_out", x -> x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2);
- Easing SINE_IN = x -> 1 - Math.cos((x - Math.PI) / 2);
- Easing SINE_OUT = x -> Math.sin((x * Math.PI) / 2);
- Easing SINE_IN_OUT = x -> -(Math.cos(Math.PI * x) - 1) / 2;
+ public static final Easing CUBIC_IN = add("cubic_in", x -> x * x * x);
+ public static final Easing CUBIC_OUT = add("cubic_out", x -> 1 - Math.pow(1 - x, 3));
+ public static final Easing CUBIC_IN_OUT = add("cubic_in_out", x -> x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2D);
- Easing QUAD_IN = x -> x * x;
- Easing QUAD_OUT = x -> 1 - (1 - x) * (1 - x);
- Easing QUAD_IN_OUT = x -> x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2;
+ public static final Easing QUART_IN = add("quart_in", x -> x * x * x * x);
+ public static final Easing QUART_OUT = add("quart_out", x -> 1 - Math.pow(1 - x, 4));
+ public static final Easing QUART_IN_OUT = add("quart_in_out", x -> x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2D);
- Easing CUBIC_IN = x -> x * x * x;
- Easing CUBIC_OUT = x -> 1 - Math.pow(1 - x, 3);
- Easing CUBIC_IN_OUT = x -> x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2D;
+ public static final Easing QUINT_IN = add("quint_in", x -> x * x * x * x * x);
+ public static final Easing QUINT_OUT = add("quint_out", x -> 1 - Math.pow(1 - x, 5));
+ public static final Easing QUINT_IN_OUT = add("quint_in_out", x -> x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2D);
- Easing QUART_IN = x -> x * x * x * x;
- Easing QUART_OUT = x -> 1 - Math.pow(1 - x, 4);
- Easing QUART_IN_OUT = x -> x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2D;
+ public static final Easing EXPO_IN = add("expo_in", x -> x == 0 ? 0 : Math.pow(2, 10 * x - 10));
+ public static final Easing EXPO_OUT = add("expo_out", x -> x == 1 ? 1 : 1 - Math.pow(2, -10 * x));
+ public static final Easing EXPO_IN_OUT = add("expo_in_out", x -> x == 0 ? 0 : x == 1 ? 1 : x < 0.5 ? Math.pow(2, 20 * x - 10) / 2 : (2 - Math.pow(2, -20 * x + 10)) / 2);
- Easing QUINT_IN = x -> x * x * x * x * x;
- Easing QUINT_OUT = x -> 1 - Math.pow(1 - x, 5);
- Easing QUINT_IN_OUT = x -> x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2D;
+ public static final Easing CIRC_IN = add("circ_in", x -> 1 - Math.sqrt(1 - x * x));
+ public static final Easing CIRC_OUT = add("circ_out", x -> Math.sqrt(1 - (x - 1) * (x - 1)));
+ public static final Easing CIRC_IN_OUT = add("circ_in_out", x -> x < 0.5 ? (1 - Math.sqrt(1 - 4 * x * x)) / 2 : (Math.sqrt(1 - (-2 * x + 2) * (-2 * x + 2)) + 1) / 2);
- Easing EXPO_IN = x -> x == 0 ? 0 : Math.pow(2, 10 * x - 10);
- Easing EXPO_OUT = x -> x == 1 ? 1 : 1 - Math.pow(2, -10 * x);
- Easing EXPO_IN_OUT = x -> x == 0 ? 0 : x == 1 ? 1 : x < 0.5 ? Math.pow(2, 20 * x - 10) / 2 : (2 - Math.pow(2, -20 * x + 10)) / 2;
+ public static final Easing BACK_IN = add("back_in", x -> x * x * (2.70158 * x - 1.70158));
+ public static final Easing BACK_OUT = add("back_out", x -> 1 - (1 - x) * (1 - x) * (2.70158 * (1 - x) - 1.70158));
+ public static final Easing BACK_IN_OUT = add("back_in_out", x -> x < 0.5 ? Math.pow(2 * x, 2) * ((2.5949095 + 1) * 2 * x - 2.5949095) / 2 : (Math.pow(2 * x - 2, 2) * ((2.5949095 + 1) * (x * 2 - 2) + 2.5949095) + 2) / 2);
- Easing CIRC_IN = x -> 1 - Math.sqrt(1 - x * x);
- Easing CIRC_OUT = x -> Math.sqrt(1 - (x - 1) * (x - 1));
- Easing CIRC_IN_OUT = x -> x < 0.5 ? (1 - Math.sqrt(1 - 4 * x * x)) / 2 : (Math.sqrt(1 - (-2 * x + 2) * (-2 * x + 2)) + 1) / 2;
+ public static final Easing ELASTIC_IN = add("elastic_in", x -> Math.sin(13 * Math.PI / 2 * x) * Math.pow(2, 10 * x - 10));
+ public static final Easing ELASTIC_OUT = add("elastic_out", x -> Math.sin(-13 * Math.PI / 2 * (x + 1)) * Math.pow(2, -10 * x) + 1);
+ public static final Easing ELASTIC_IN_OUT = add("elastic_in_out", x -> x < 0.5 ? Math.sin(13 * Math.PI / 2 * (2 * x)) * Math.pow(2, 10 * (2 * x) - 10) / 2 : Math.sin(-13 * Math.PI / 2 * (2 * x - 1)) * Math.pow(2, -10 * (2 * x - 1)) / 2 + 1);
- Easing BACK_IN = x -> x * x * (2.70158 * x - 1.70158);
- Easing BACK_OUT = x -> 1 - (1 - x) * (1 - x) * (2.70158 * (1 - x) - 1.70158);
- Easing BACK_IN_OUT = x -> x < 0.5 ? Math.pow(2 * x, 2) * ((2.5949095 + 1) * 2 * x - 2.5949095) / 2 : (Math.pow(2 * x - 2, 2) * ((2.5949095 + 1) * (x * 2 - 2) + 2.5949095) + 2) / 2;
-
- Easing ELASTIC_IN = x -> Math.sin(13 * Math.PI / 2 * x) * Math.pow(2, 10 * x - 10);
- Easing ELASTIC_OUT = x -> Math.sin(-13 * Math.PI / 2 * (x + 1)) * Math.pow(2, -10 * x) + 1;
- Easing ELASTIC_IN_OUT = x -> x < 0.5 ? Math.sin(13 * Math.PI / 2 * (2 * x)) * Math.pow(2, 10 * (2 * x) - 10) / 2 : Math.sin(-13 * Math.PI / 2 * (2 * x - 1)) * Math.pow(2, -10 * (2 * x - 1)) / 2 + 1;
-
- Easing BOUNCE_OUT = x -> {
+ public static final Easing BOUNCE_OUT = add("bounce_out", x -> {
if (x < 1 / 2.75) {
return 7.5625 * x * x;
} else if (x < 2 / 2.75) {
@@ -76,8 +70,33 @@ default Vec3d lerp(double t, Vec3d a, Vec3d b) {
} else {
return 7.5625 * (x -= 2.625 / 2.75) * x + 0.984375;
}
- };
+ });
+
+ public static final Easing BOUNCE_IN = add("bounce_in", x -> 1 - BOUNCE_OUT.ease(1 - x));
+ public static final Easing BOUNCE_IN_OUT = add("bounce_in_out", x -> x < 0.5 ? BOUNCE_IN.ease(x * 2) / 2 : BOUNCE_OUT.ease(x * 2 - 1) / 2 + 0.5);
+
+ public final String id;
+ public final Double2DoubleFunction function;
- Easing BOUNCE_IN = x -> 1 - BOUNCE_OUT.ease(1 - x);
- Easing BOUNCE_IN_OUT = x -> x < 0.5 ? BOUNCE_IN.ease(x * 2) / 2 : BOUNCE_OUT.ease(x * 2 - 1) / 2 + 0.5;
+ private Easing(String id, Double2DoubleFunction function) {
+ this.id = id;
+ this.function = function;
+ }
+
+ public double ease(double x) {
+ return function.get(x);
+ }
+
+ public double easeClamped(double x) {
+ return function.get(KMath.clamp(x, 0D, 1D));
+ }
+
+ public double lerp(double t, double a, double b) {
+ return KMath.lerp(function.get(t), a, b);
+ }
+
+ public Vec3d lerp(double t, Vec3d a, Vec3d b) {
+ var e = function.get(t);
+ return new Vec3d(KMath.lerp(e, a.x, b.x), KMath.lerp(e, a.y, b.y), KMath.lerp(e, a.z, b.z));
+ }
}
diff --git a/src/main/java/dev/latvian/mods/kmath/util/EasingGroup.java b/src/main/java/dev/latvian/mods/kmath/util/EasingGroup.java
index a20d252..82b7eab 100644
--- a/src/main/java/dev/latvian/mods/kmath/util/EasingGroup.java
+++ b/src/main/java/dev/latvian/mods/kmath/util/EasingGroup.java
@@ -3,56 +3,43 @@
import java.util.LinkedHashMap;
import java.util.Map;
-/**
- * Source
- */
-public enum EasingGroup {
- LINEAR("linear", Easing.LINEAR),
- SMOOTHSTEP("smoothstep", Easing.SMOOTHSTEP),
- ISMOOTHSTEP("ismoothstep", Easing.ISMOOTHSTEP),
- SMOOTHERSTEP("smootherstep", Easing.SMOOTHERSTEP),
- SINE("sine", Easing.SINE_IN, Easing.SINE_OUT, Easing.SINE_IN_OUT),
- QUAD("quad", Easing.QUAD_IN, Easing.QUAD_OUT, Easing.QUAD_IN_OUT),
- CUBIC("cubic", Easing.CUBIC_IN, Easing.CUBIC_OUT, Easing.CUBIC_IN_OUT),
- QUART("quart", Easing.QUART_IN, Easing.QUART_OUT, Easing.QUART_IN_OUT),
- QUINT("quint", Easing.QUINT_IN, Easing.QUINT_OUT, Easing.QUINT_IN_OUT),
- EXPO("expo", Easing.EXPO_IN, Easing.EXPO_OUT, Easing.EXPO_IN_OUT),
- CIRC("circ", Easing.CIRC_IN, Easing.CIRC_OUT, Easing.CIRC_IN_OUT),
- BACK("back", Easing.BACK_IN, Easing.BACK_OUT, Easing.BACK_IN_OUT),
- ELASTIC("elastic", Easing.ELASTIC_IN, Easing.ELASTIC_OUT, Easing.ELASTIC_IN_OUT),
- BOUNCE("bounce", Easing.BOUNCE_IN, Easing.BOUNCE_OUT, Easing.BOUNCE_IN_OUT);
-
- public static final EasingGroup[] VALUES = values();
+public class EasingGroup {
public static final Map GROUPS = new LinkedHashMap<>();
- public static final Map FUNCTIONS = new LinkedHashMap<>();
- static {
- for (var group : VALUES) {
- GROUPS.put(group.id, group);
+ public static EasingGroup add(String id, Easing in, Easing out, Easing inOut) {
+ var group = new EasingGroup(id, in, out, inOut);
+ GROUPS.put(id, group);
+ return group;
+ }
- if (group.in == group.out && group.in == group.inOut) {
- FUNCTIONS.put(group.id, group.in);
- } else {
- FUNCTIONS.put(group.id + "_in", group.in);
- FUNCTIONS.put(group.id + "_out", group.out);
- FUNCTIONS.put(group.id + "_in_out", group.inOut);
- }
- }
+ public static EasingGroup add(String id, Easing easing) {
+ return add(id, easing, easing, easing);
}
+ public static final EasingGroup LINEAR = add("linear", Easing.LINEAR);
+ public static final EasingGroup SMOOTHSTEP = add("smoothstep", Easing.SMOOTHSTEP);
+ public static final EasingGroup ISMOOTHSTEP = add("ismoothstep", Easing.ISMOOTHSTEP);
+ public static final EasingGroup SMOOTHERSTEP = add("smootherstep", Easing.SMOOTHERSTEP);
+ public static final EasingGroup SINE = add("sine", Easing.SINE_IN, Easing.SINE_OUT, Easing.SINE_IN_OUT);
+ public static final EasingGroup QUAD = add("quad", Easing.QUAD_IN, Easing.QUAD_OUT, Easing.QUAD_IN_OUT);
+ public static final EasingGroup CUBIC = add("cubic", Easing.CUBIC_IN, Easing.CUBIC_OUT, Easing.CUBIC_IN_OUT);
+ public static final EasingGroup QUART = add("quart", Easing.QUART_IN, Easing.QUART_OUT, Easing.QUART_IN_OUT);
+ public static final EasingGroup QUINT = add("quint", Easing.QUINT_IN, Easing.QUINT_OUT, Easing.QUINT_IN_OUT);
+ public static final EasingGroup EXPO = add("expo", Easing.EXPO_IN, Easing.EXPO_OUT, Easing.EXPO_IN_OUT);
+ public static final EasingGroup CIRC = add("circ", Easing.CIRC_IN, Easing.CIRC_OUT, Easing.CIRC_IN_OUT);
+ public static final EasingGroup BACK = add("back", Easing.BACK_IN, Easing.BACK_OUT, Easing.BACK_IN_OUT);
+ public static final EasingGroup ELASTIC = add("elastic", Easing.ELASTIC_IN, Easing.ELASTIC_OUT, Easing.ELASTIC_IN_OUT);
+ public static final EasingGroup BOUNCE = add("bounce", Easing.BOUNCE_IN, Easing.BOUNCE_OUT, Easing.BOUNCE_IN_OUT);
+
public final String id;
public final Easing in;
public final Easing out;
public final Easing inOut;
- EasingGroup(String id, Easing in, Easing out, Easing inOut) {
+ private EasingGroup(String id, Easing in, Easing out, Easing inOut) {
this.id = id;
this.in = in;
this.out = out;
this.inOut = inOut;
}
-
- EasingGroup(String id, Easing common) {
- this(id, common, common, common);
- }
}