From 5ab360ba7fa908fba7079b952ca938cea1f9b46c Mon Sep 17 00:00:00 2001 From: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> Date: Fri, 12 May 2023 22:44:33 -0700 Subject: [PATCH] Use new transformation cmpnt vs legacy rotation Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com> --- .../component/CustomBlockComponents.java | 10 ++--- ...nent.java => TransformationComponent.java} | 28 ++++++++++++- .../block/GeyserCustomBlockComponents.java | 20 ++++----- .../mappings/versions/MappingsReader_v1.java | 38 ++++++++++++++--- .../CustomBlockRegistryPopulator.java | 17 +++++--- .../geyser/registry/type/CustomSkull.java | 10 ++--- .../org/geysermc/geyser/util/MathUtils.java | 42 +++++++++++++++++++ 7 files changed, 131 insertions(+), 34 deletions(-) rename api/src/main/java/org/geysermc/geyser/api/block/custom/component/{RotationComponent.java => TransformationComponent.java} (53%) diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java index aa02c91fa..7cde309f6 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/CustomBlockComponents.java @@ -118,12 +118,12 @@ public interface CustomBlockComponents { @Nullable Integer lightDampening(); /** - * Gets the rotation component - * Equivalent to "minecraft:rotation" + * Gets the transformation component + * Equivalent to "minecraft:transformation" * - * @return The rotation. + * @return The transformation. */ - @Nullable RotationComponent rotation(); + @Nullable TransformationComponent transformation(); /** * Gets the unit cube component @@ -170,7 +170,7 @@ public interface CustomBlockComponents { Builder lightDampening(Integer lightDampening); - Builder rotation(RotationComponent rotation); + Builder transformation(TransformationComponent transformation); Builder unitCube(boolean unitCube); diff --git a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/RotationComponent.java b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/TransformationComponent.java similarity index 53% rename from api/src/main/java/org/geysermc/geyser/api/block/custom/component/RotationComponent.java rename to api/src/main/java/org/geysermc/geyser/api/block/custom/component/TransformationComponent.java index 610b5365b..5f4f08b51 100644 --- a/api/src/main/java/org/geysermc/geyser/api/block/custom/component/RotationComponent.java +++ b/api/src/main/java/org/geysermc/geyser/api/block/custom/component/TransformationComponent.java @@ -26,7 +26,31 @@ package org.geysermc.geyser.api.block.custom.component; /** - * This class is used to store a rotation component for a custom block. + * This class is used to store the transformation component of a block */ -public record RotationComponent(int x, int y, int z) { +public record TransformationComponent(int rx, int ry, int rz, float sx, float sy, float sz, float tx, float ty, float tz) { + /** + * Constructs a new TransformationComponent with the rotation values and assumes default scale and translation + * + * @param rx The rotation on the x axis + * @param ry The rotation on the y axis + * @param rz The rotation on the z axis + */ + public TransformationComponent(int rx, int ry, int rz) { + this(rx, ry, rz, 1, 1, 1, 0, 0, 0); + } + + /** + * Constructs a new TransformationComponent with the rotation and scale values and assumes default translation + * + * @param rx The rotation on the x axis + * @param ry The rotation on the y axis + * @param rz The rotation on the z axis + * @param sx The scale on the x axis + * @param sy The scale on the y axis + * @param sz The scale on the z axis + */ + public TransformationComponent(int rx, int ry, int rz, float sx, float sy, float sz) { + this(rx, ry, rz, sx, sy, sz, 0, 0, 0); + } } diff --git a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java index c58d35fea..65a65a436 100644 --- a/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java +++ b/core/src/main/java/org/geysermc/geyser/level/block/GeyserCustomBlockComponents.java @@ -35,7 +35,7 @@ import org.geysermc.geyser.api.block.custom.component.BoxComponent; import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; import org.geysermc.geyser.api.block.custom.component.MaterialInstance; import org.geysermc.geyser.api.block.custom.component.PlacementConditions; -import org.geysermc.geyser.api.block.custom.component.RotationComponent; +import org.geysermc.geyser.api.block.custom.component.TransformationComponent; import org.jetbrains.annotations.NotNull; import java.util.HashSet; @@ -55,7 +55,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { Float friction; Integer lightEmission; Integer lightDampening; - RotationComponent rotation; + TransformationComponent transformation; boolean unitCube; boolean placeAir; Set tags; @@ -75,7 +75,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { this.friction = builder.friction; this.lightEmission = builder.lightEmission; this.lightDampening = builder.lightDampening; - this.rotation = builder.rotation; + this.transformation = builder.transformation; this.unitCube = builder.unitCube; this.placeAir = builder.placeAir; if (builder.tags.isEmpty()) { @@ -136,8 +136,8 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { } @Override - public RotationComponent rotation() { - return rotation; + public TransformationComponent transformation() { + return transformation; } @Override @@ -166,7 +166,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { protected Float friction; protected Integer lightEmission; protected Integer lightDampening; - protected RotationComponent rotation; + protected TransformationComponent transformation; protected boolean unitCube = false; protected boolean placeAir = false; protected final Set tags = new HashSet<>(); @@ -270,11 +270,11 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents { } @Override - public Builder rotation(RotationComponent rotation) { - if (rotation.x() % 90 != 0 || rotation.y() % 90 != 0 || rotation.z() % 90 != 0) { - throw new IllegalArgumentException("Rotation must be a multiple of 90 degrees."); + public Builder transformation(TransformationComponent transformation) { + if (transformation.rx() % 90 != 0 || transformation.ry() % 90 != 0 || transformation.rz() % 90 != 0) { + throw new IllegalArgumentException("Rotation of transformation must be a multiple of 90 degrees."); } - this.rotation = rotation; + this.transformation = transformation; return this; } diff --git a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java index 44689aba4..99262dab4 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java +++ b/core/src/main/java/org/geysermc/geyser/registry/mappings/versions/MappingsReader_v1.java @@ -367,12 +367,38 @@ public class MappingsReader_v1 extends MappingsReader { } builder.placeAir(placeAir); - if (node.has("rotation")) { - JsonNode rotation = node.get("rotation"); - int rotationX = rotation.get(0).asInt(); - int rotationY = rotation.get(1).asInt(); - int rotationZ = rotation.get(2).asInt(); - builder.rotation(new RotationComponent(rotationX, rotationY, rotationZ)); + if (node.has("transformation")) { + JsonNode transformation = node.get("transformation"); + + int rotationX = 0; + int rotationY = 0; + int rotationZ = 0; + float scaleX = 1; + float scaleY = 1; + float scaleZ = 1; + float transformX = 0; + float transformY = 0; + float transformZ = 0; + + if (transformation.has("rotation")) { + JsonNode rotation = transformation.get("rotation"); + rotationX = rotation.get(0).asInt(); + rotationY = rotation.get(1).asInt(); + rotationZ = rotation.get(2).asInt(); + } + if (transformation.has("scale")) { + JsonNode scale = transformation.get("scale"); + scaleX = scale.get(0).floatValue(); + scaleY = scale.get(1).floatValue(); + scaleZ = scale.get(2).floatValue(); + } + if (transformation.has("translation")) { + JsonNode translation = transformation.get("translation"); + transformX = translation.get(0).floatValue(); + transformY = translation.get(1).floatValue(); + transformZ = translation.get(2).floatValue(); + } + builder.transformation(new TransformationComponent(rotationX, rotationY, rotationZ, scaleX, scaleY, scaleZ, transformX, transformY, transformZ)); } if (node.has("unit_cube")) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java index 9ef71c423..942990b9d 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java +++ b/core/src/main/java/org/geysermc/geyser/registry/populator/CustomBlockRegistryPopulator.java @@ -26,6 +26,7 @@ import org.geysermc.geyser.level.block.GeyserCustomBlockData.CustomBlockDataBuil import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.mappings.MappingsConfigReader; import org.geysermc.geyser.registry.type.CustomSkull; +import org.geysermc.geyser.util.MathUtils; import java.util.ArrayList; import java.util.HashMap; @@ -286,11 +287,17 @@ public class CustomBlockRegistryPopulator { .putByte("lightLevel", components.lightDampening().byteValue()) .build()); } - if (components.rotation() != null) { - builder.putCompound("minecraft:rotation", NbtMap.builder() - .putFloat("x", components.rotation().x()) - .putFloat("y", components.rotation().y()) - .putFloat("z", components.rotation().z()) + if (components.transformation() != null) { + builder.putCompound("minecraft:transformation", NbtMap.builder() + .putInt("RX", MathUtils.unwrapDegreesToInt(components.transformation().rx()) / 90) + .putInt("RY", MathUtils.unwrapDegreesToInt(components.transformation().ry()) / 90) + .putInt("RZ", MathUtils.unwrapDegreesToInt(components.transformation().rz()) / 90) + .putFloat("SX", components.transformation().sx()) + .putFloat("SY", components.transformation().sy()) + .putFloat("SZ", components.transformation().sz()) + .putFloat("TX", components.transformation().tx()) + .putFloat("TY", components.transformation().ty()) + .putFloat("TZ", components.transformation().tz()) .build()); } if (components.unitCube()) { diff --git a/core/src/main/java/org/geysermc/geyser/registry/type/CustomSkull.java b/core/src/main/java/org/geysermc/geyser/registry/type/CustomSkull.java index 08c0b80a4..b23a607d3 100644 --- a/core/src/main/java/org/geysermc/geyser/registry/type/CustomSkull.java +++ b/core/src/main/java/org/geysermc/geyser/registry/type/CustomSkull.java @@ -32,7 +32,7 @@ import org.geysermc.geyser.api.block.custom.CustomBlockState; import org.geysermc.geyser.api.block.custom.component.BoxComponent; import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; import org.geysermc.geyser.api.block.custom.component.MaterialInstance; -import org.geysermc.geyser.api.block.custom.component.RotationComponent; +import org.geysermc.geyser.api.block.custom.component.TransformationComponent; import org.geysermc.geyser.level.block.GeyserCustomBlockComponents; import org.geysermc.geyser.level.block.GeyserCustomBlockData; @@ -110,7 +110,7 @@ public class CustomSkull { private void addDefaultPermutation(List permutations) { CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder() .geometry("geometry.geyser.player_skull_hand") - .rotation(new RotationComponent(0, 180, 0)) + .transformation(new TransformationComponent(0, 180, 0)) .build(); String condition = String.format("query.block_property('%s') == 0 && query.block_property('%s') == 0", BITS_A_PROPERTY, BITS_B_PROPERTY); @@ -121,14 +121,13 @@ public class CustomSkull { String[] quadrantNames = {"a", "b", "c", "d"}; for (int quadrant = 0; quadrant < 4; quadrant++) { - RotationComponent rotation = new RotationComponent(0, ROTATIONS[quadrant], 0); for (int i = 0; i < 4; i++) { int floorRotation = 4 * quadrant + i; CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder() .selectionBox(FLOOR_BOX) .collisionBox(FLOOR_BOX) .geometry("geometry.geyser.player_skull_floor_" + quadrantNames[i]) - .rotation(rotation) + .transformation(new TransformationComponent(0, ROTATIONS[quadrant], 0)) .build(); int bitsA = (5 + floorRotation) % 7; @@ -141,12 +140,11 @@ public class CustomSkull { private void addWallPermutations(List permutations) { for (int i = 0; i < 4; i++) { - RotationComponent rotation = new RotationComponent(0, ROTATIONS[i], 0); CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder() .selectionBox(WALL_BOX) .collisionBox(WALL_BOX) .geometry("geometry.geyser.player_skull_wall") - .rotation(rotation) + .transformation(new TransformationComponent(0, ROTATIONS[i], 0)) .build(); String condition = String.format("query.block_property('%s') == %d && query.block_property('%s') == %d", BITS_A_PROPERTY, i + 1, BITS_B_PROPERTY, 0); diff --git a/core/src/main/java/org/geysermc/geyser/util/MathUtils.java b/core/src/main/java/org/geysermc/geyser/util/MathUtils.java index df9ee533b..d0675fa64 100644 --- a/core/src/main/java/org/geysermc/geyser/util/MathUtils.java +++ b/core/src/main/java/org/geysermc/geyser/util/MathUtils.java @@ -28,6 +28,11 @@ package org.geysermc.geyser.util; public class MathUtils { public static final double SQRT_OF_TWO = Math.sqrt(2); + /** + * Wrap the given float degrees to be between -180.0 and 180.0. + * @param degrees The degrees value to wrap + * @return The wrapped degrees value between -180.0 and 180.0 + */ public static float wrapDegrees(float degrees) { degrees = degrees % 360.0f; if (degrees < -180.0f) { @@ -38,14 +43,51 @@ public class MathUtils { return degrees; } + /** + * Wrap the given double degrees to be between -180.0 and 180.0. + * @param degrees The degrees value to wrap + * @return The wrapped degrees value between -180.0 and 180.0 + */ public static float wrapDegrees(double degrees) { return wrapDegrees((float) degrees); } + /** + * Wrap the given degrees to be between -180 and 180 as an integer. + * @param degrees The degrees value to wrap + * @return The wrapped degrees value between -180 and 180 as an integer + */ public static int wrapDegreesToInt(float degrees) { return (int) wrapDegrees(degrees); } + /** + * Unwrap the given float degrees to be between 0.0 and 360.0. + * @param degrees The degrees value to unwrap + * @return The unwrapped degrees value between 0.0 and 360.0 + */ + public static float unwrapDegrees(float degrees) { + return (degrees % 360 + 360) % 360; + } + + /** + * Unwrap the given double degrees to be between 0.0 and 360.0. + * @param degrees The degrees value to unwrap + * @return The unwrapped degrees value between 0.0 and 360.0 + */ + public static float unwrapDegrees(double degrees) { + return unwrapDegrees((float) degrees); + } + + /** + * Unwrap the given degrees to be between 0 and 360 as an integer. + * @param degrees The degrees value to unwrap + * @return The unwrapped degrees value between 0 and 360 as an integer + */ + public static int unwrapDegreesToInt(float degrees) { + return (int) unwrapDegrees(degrees); + } + /** * Round the given float to the next whole number *