From 2efefe25b3f901be45c3a366c381d0d8ac33e511 Mon Sep 17 00:00:00 2001 From: TheMode Date: Fri, 9 Jul 2021 18:53:13 +0200 Subject: [PATCH] Improve RelativeVec api --- .../relative/ArgumentRelativeVec.java | 27 +++-- .../server/utils/location/RelativeVec.java | 98 ++++++++++--------- 2 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/main/java/net/minestom/server/command/builder/arguments/relative/ArgumentRelativeVec.java b/src/main/java/net/minestom/server/command/builder/arguments/relative/ArgumentRelativeVec.java index ed8460764..76a26fde4 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/relative/ArgumentRelativeVec.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/relative/ArgumentRelativeVec.java @@ -15,9 +15,9 @@ import java.util.function.Function; */ abstract class ArgumentRelativeVec extends Argument { - public static final char RELATIVE_CHAR = '~'; - public static final char LOCAL_CHAR = '^'; - public static final Set MODIFIER_CHARS = Set.of(RELATIVE_CHAR, LOCAL_CHAR); + private static final char RELATIVE_CHAR = '~'; + private static final char LOCAL_CHAR = '^'; + private static final Set MODIFIER_CHARS = Set.of(RELATIVE_CHAR, LOCAL_CHAR); public static final int INVALID_NUMBER_COUNT_ERROR = 1; public static final int INVALID_NUMBER_ERROR = 2; @@ -31,6 +31,7 @@ abstract class ArgumentRelativeVec extends Argument { } abstract Function getRelativeNumberParser(); + abstract Function getAbsoluteNumberParser(); @NotNull @@ -43,7 +44,7 @@ abstract class ArgumentRelativeVec extends Argument { double[] coordinates = new double[split.length]; boolean[] isRelative = new boolean[split.length]; - Type type = Type.UNDEFINED; + var type = RelativeVec.CoordinateType.UNDEFINED; for (int i = 0; i < split.length; i++) { final String element = split[i]; try { @@ -51,9 +52,9 @@ abstract class ArgumentRelativeVec extends Argument { if (MODIFIER_CHARS.contains(modifierChar)) { isRelative[i] = true; - if (type == Type.UNDEFINED) { - type = modifierChar == LOCAL_CHAR ? Type.LOCAL : Type.RELATIVE; - } else if (type != (modifierChar == LOCAL_CHAR ? Type.LOCAL : Type.RELATIVE)) { + if (type == RelativeVec.CoordinateType.UNDEFINED) { + type = modifierChar == LOCAL_CHAR ? RelativeVec.CoordinateType.LOCAL : RelativeVec.CoordinateType.RELATIVE; + } else if (type != (modifierChar == LOCAL_CHAR ? RelativeVec.CoordinateType.LOCAL : RelativeVec.CoordinateType.RELATIVE)) { throw new ArgumentSyntaxException("Cannot mix world & local coordinates (everything must either use ^ or not)", input, MIXED_TYPE_ERROR); } @@ -69,8 +70,10 @@ abstract class ArgumentRelativeVec extends Argument { } } - return new RelativeVec(split.length == 3 ? new Vec(coordinates[0], coordinates[1], coordinates[2]) : new Vec(coordinates[0], coordinates[1]), - isRelative, type == Type.LOCAL); + return new RelativeVec(split.length == 3 ? + new Vec(coordinates[0], coordinates[1], coordinates[2]) : new Vec(coordinates[0], coordinates[1]), + type, + isRelative[0], isRelative[1], isRelative[2]); } /** @@ -81,10 +84,4 @@ abstract class ArgumentRelativeVec extends Argument { public int getNumberCount() { return numberCount; } - - private enum Type { - RELATIVE, - LOCAL, - UNDEFINED - } } diff --git a/src/main/java/net/minestom/server/utils/location/RelativeVec.java b/src/main/java/net/minestom/server/utils/location/RelativeVec.java index b9704eae6..e9a2ddffe 100644 --- a/src/main/java/net/minestom/server/utils/location/RelativeVec.java +++ b/src/main/java/net/minestom/server/utils/location/RelativeVec.java @@ -1,7 +1,6 @@ package net.minestom.server.utils.location; import net.minestom.server.command.CommandSender; -import net.minestom.server.coordinate.Point; import net.minestom.server.coordinate.Pos; import net.minestom.server.coordinate.Vec; import net.minestom.server.entity.Entity; @@ -18,38 +17,26 @@ import java.util.Objects; public final class RelativeVec { private final Vec vec; - private boolean relativeX, relativeY, relativeZ; - private boolean[] relative; - private boolean isLocal; + private final CoordinateType coordinateType; + private final boolean relativeX, relativeY, relativeZ; - public RelativeVec(@NotNull Vec vec, boolean relativeX, boolean relativeY, boolean relativeZ) { + public RelativeVec(@NotNull Vec vec, @NotNull CoordinateType coordinateType, boolean relativeX, boolean relativeY, boolean relativeZ) { this.vec = vec; + this.coordinateType = coordinateType; this.relativeX = relativeX; this.relativeY = relativeY; this.relativeZ = relativeZ; } - public RelativeVec(Vec vec, boolean[] relative, boolean isLocal) { - this.vec = vec; - this.relative = relative; - this.isLocal = isLocal; - } - /** * Gets the location based on the relative fields and {@code position}. * - * @param point the relative position + * @param origin the origin position, null if none * @return the location */ - public @NotNull Vec from(@Nullable Point point) { - if (!relativeX && !relativeY && !relativeZ) { - return vec; - } - final var absolute = Objects.requireNonNullElse(point, Vec.ZERO); - final double x = vec.x() + (relativeX ? absolute.x() : 0); - final double y = vec.y() + (relativeY ? absolute.y() : 0); - final double z = vec.z() + (relativeZ ? absolute.z() : 0); - return new Vec(x, y, z); + public @NotNull Vec from(@Nullable Pos origin) { + origin = Objects.requireNonNullElse(origin, Pos.ZERO); + return coordinateType.convert(vec, origin, relativeX, relativeY, relativeZ); } @ApiStatus.Experimental @@ -70,9 +57,8 @@ public final class RelativeVec { * @return the location */ public @NotNull Vec from(@Nullable Entity entity) { - return isLocal ? toGlobal(vec, entity.getPosition(), relative) : toGlobal(vec, entity.getPosition().asVec(), relative); -// final var entityPosition = entity != null ? entity.getPosition() : Pos.ZERO; -// return from(entityPosition); + final var entityPosition = entity != null ? entity.getPosition() : Pos.ZERO; + return from(entityPosition); } public @NotNull Vec fromSender(@Nullable CommandSender sender) { @@ -113,30 +99,48 @@ public final class RelativeVec { return relativeZ; } - public static Vec toGlobal(Vec local, Pos origin, boolean[] axis) { - double double5 = Math.cos(Math.toRadians(origin.yaw() + 90.0f)); - double double6 = Math.sin(Math.toRadians(origin.yaw() + 90.0f)); - double double7 = Math.cos(Math.toRadians(-origin.pitch())); - double double8 = Math.sin(Math.toRadians(-origin.pitch())); - double double9 = Math.cos(Math.toRadians(-origin.pitch() + 90.0f)); - double double10 = Math.sin(Math.toRadians(-origin.pitch() + 90.0f)); - Vec dna11 = new Vec(double5 * double7, double8, double6 * double7); - Vec dna12 = new Vec(double5 * double9, double10, double6 * double9); - Vec dna13 = dna11.cross(dna12).mul(-1); - double double14 = dna11.x() * local.z() + dna12.x() * local.y() + dna13.x() * local.x(); - double double16 = dna11.y() * local.z() + dna12.y() * local.y() + dna13.y() * local.x(); - double double18 = dna11.z() * local.z() + dna12.z() * local.y() + dna13.z() * local.x(); - return new Vec(double14 + (axis[0] ? origin.x() : 0), double16 + (axis[1] ? origin.y() : 0), double18 + (axis[2] ? origin.z() : 0)); + public enum CoordinateType { + RELATIVE((relative, origin, relativeX, relativeY, relativeZ) -> { + if (!relativeX && !relativeY && !relativeZ) { + return relative; + } + final var absolute = Objects.requireNonNullElse(origin, Vec.ZERO); + final double x = relative.x() + (relativeX ? absolute.x() : 0); + final double y = relative.y() + (relativeY ? absolute.y() : 0); + final double z = relative.z() + (relativeZ ? absolute.z() : 0); + return new Vec(x, y, z); + }), + LOCAL((local, origin, relativeX, relativeY, relativeZ) -> { + double double5 = Math.cos(Math.toRadians(origin.yaw() + 90.0f)); + double double6 = Math.sin(Math.toRadians(origin.yaw() + 90.0f)); + double double7 = Math.cos(Math.toRadians(-origin.pitch())); + double double8 = Math.sin(Math.toRadians(-origin.pitch())); + double double9 = Math.cos(Math.toRadians(-origin.pitch() + 90.0f)); + double double10 = Math.sin(Math.toRadians(-origin.pitch() + 90.0f)); + Vec dna11 = new Vec(double5 * double7, double8, double6 * double7); + Vec dna12 = new Vec(double5 * double9, double10, double6 * double9); + Vec dna13 = dna11.cross(dna12).mul(-1); + double double14 = dna11.x() * local.z() + dna12.x() * local.y() + dna13.x() * local.x(); + double double16 = dna11.y() * local.z() + dna12.y() * local.y() + dna13.y() * local.x(); + double double18 = dna11.z() * local.z() + dna12.z() * local.y() + dna13.z() * local.x(); + return new Vec(double14 + (relativeX ? origin.x() : 0), + double16 + (relativeY ? origin.y() : 0), + double18 + (relativeZ ? origin.z() : 0)); + }), + UNDEFINED((vec, origin, relativeX, relativeY, relativeZ) -> vec); + + private final CoordinateConverter converter; + + CoordinateType(CoordinateConverter converter) { + this.converter = converter; + } + + private @NotNull Vec convert(Vec vec, Pos origin, boolean relativeX, boolean relativeY, boolean relativeZ) { + return converter.convert(vec, origin, relativeX, relativeY, relativeZ); + } } - public static Vec toGlobal(Vec relative, Vec origin, boolean[] axis) { - if (!axis[0] && !axis[1] && !axis[2]) { - return relative; - } - final var absolute = Objects.requireNonNullElse(origin, Vec.ZERO); - final double x = relative.x() + (axis[0] ? absolute.x() : 0); - final double y = relative.y() + (axis[1] ? absolute.y() : 0); - final double z = relative.z() + (axis[2] ? absolute.z() : 0); - return new Vec(x, y, z); + private interface CoordinateConverter { + @NotNull Vec convert(Vec vec, Pos origin, boolean relativeX, boolean relativeY, boolean relativeZ); } }