Use new transformation cmpnt vs legacy rotation

Signed-off-by: Joshua Castle <26531652+Kas-tle@users.noreply.github.com>
This commit is contained in:
Joshua Castle 2023-05-12 22:44:33 -07:00
parent cd62048a4d
commit 5ab360ba7f
No known key found for this signature in database
GPG key ID: F674F38216C35D5D
7 changed files with 131 additions and 34 deletions

View file

@ -118,12 +118,12 @@ public interface CustomBlockComponents {
@Nullable Integer lightDampening(); @Nullable Integer lightDampening();
/** /**
* Gets the rotation component * Gets the transformation component
* Equivalent to "minecraft:rotation" * Equivalent to "minecraft:transformation"
* *
* @return The rotation. * @return The transformation.
*/ */
@Nullable RotationComponent rotation(); @Nullable TransformationComponent transformation();
/** /**
* Gets the unit cube component * Gets the unit cube component
@ -170,7 +170,7 @@ public interface CustomBlockComponents {
Builder lightDampening(Integer lightDampening); Builder lightDampening(Integer lightDampening);
Builder rotation(RotationComponent rotation); Builder transformation(TransformationComponent transformation);
Builder unitCube(boolean unitCube); Builder unitCube(boolean unitCube);

View file

@ -26,7 +26,31 @@
package org.geysermc.geyser.api.block.custom.component; 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);
}
} }

View file

@ -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.CustomBlockComponents;
import org.geysermc.geyser.api.block.custom.component.MaterialInstance; 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.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 org.jetbrains.annotations.NotNull;
import java.util.HashSet; import java.util.HashSet;
@ -55,7 +55,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
Float friction; Float friction;
Integer lightEmission; Integer lightEmission;
Integer lightDampening; Integer lightDampening;
RotationComponent rotation; TransformationComponent transformation;
boolean unitCube; boolean unitCube;
boolean placeAir; boolean placeAir;
Set<String> tags; Set<String> tags;
@ -75,7 +75,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
this.friction = builder.friction; this.friction = builder.friction;
this.lightEmission = builder.lightEmission; this.lightEmission = builder.lightEmission;
this.lightDampening = builder.lightDampening; this.lightDampening = builder.lightDampening;
this.rotation = builder.rotation; this.transformation = builder.transformation;
this.unitCube = builder.unitCube; this.unitCube = builder.unitCube;
this.placeAir = builder.placeAir; this.placeAir = builder.placeAir;
if (builder.tags.isEmpty()) { if (builder.tags.isEmpty()) {
@ -136,8 +136,8 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
} }
@Override @Override
public RotationComponent rotation() { public TransformationComponent transformation() {
return rotation; return transformation;
} }
@Override @Override
@ -166,7 +166,7 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
protected Float friction; protected Float friction;
protected Integer lightEmission; protected Integer lightEmission;
protected Integer lightDampening; protected Integer lightDampening;
protected RotationComponent rotation; protected TransformationComponent transformation;
protected boolean unitCube = false; protected boolean unitCube = false;
protected boolean placeAir = false; protected boolean placeAir = false;
protected final Set<String> tags = new HashSet<>(); protected final Set<String> tags = new HashSet<>();
@ -270,11 +270,11 @@ public class GeyserCustomBlockComponents implements CustomBlockComponents {
} }
@Override @Override
public Builder rotation(RotationComponent rotation) { public Builder transformation(TransformationComponent transformation) {
if (rotation.x() % 90 != 0 || rotation.y() % 90 != 0 || rotation.z() % 90 != 0) { if (transformation.rx() % 90 != 0 || transformation.ry() % 90 != 0 || transformation.rz() % 90 != 0) {
throw new IllegalArgumentException("Rotation must be a multiple of 90 degrees."); throw new IllegalArgumentException("Rotation of transformation must be a multiple of 90 degrees.");
} }
this.rotation = rotation; this.transformation = transformation;
return this; return this;
} }

View file

@ -367,12 +367,38 @@ public class MappingsReader_v1 extends MappingsReader {
} }
builder.placeAir(placeAir); builder.placeAir(placeAir);
if (node.has("rotation")) { if (node.has("transformation")) {
JsonNode rotation = node.get("rotation"); JsonNode transformation = node.get("transformation");
int rotationX = rotation.get(0).asInt();
int rotationY = rotation.get(1).asInt(); int rotationX = 0;
int rotationZ = rotation.get(2).asInt(); int rotationY = 0;
builder.rotation(new RotationComponent(rotationX, rotationY, rotationZ)); 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")) { if (node.has("unit_cube")) {

View file

@ -26,6 +26,7 @@ import org.geysermc.geyser.level.block.GeyserCustomBlockData.CustomBlockDataBuil
import org.geysermc.geyser.registry.BlockRegistries; import org.geysermc.geyser.registry.BlockRegistries;
import org.geysermc.geyser.registry.mappings.MappingsConfigReader; import org.geysermc.geyser.registry.mappings.MappingsConfigReader;
import org.geysermc.geyser.registry.type.CustomSkull; import org.geysermc.geyser.registry.type.CustomSkull;
import org.geysermc.geyser.util.MathUtils;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
@ -286,11 +287,17 @@ public class CustomBlockRegistryPopulator {
.putByte("lightLevel", components.lightDampening().byteValue()) .putByte("lightLevel", components.lightDampening().byteValue())
.build()); .build());
} }
if (components.rotation() != null) { if (components.transformation() != null) {
builder.putCompound("minecraft:rotation", NbtMap.builder() builder.putCompound("minecraft:transformation", NbtMap.builder()
.putFloat("x", components.rotation().x()) .putInt("RX", MathUtils.unwrapDegreesToInt(components.transformation().rx()) / 90)
.putFloat("y", components.rotation().y()) .putInt("RY", MathUtils.unwrapDegreesToInt(components.transformation().ry()) / 90)
.putFloat("z", components.rotation().z()) .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()); .build());
} }
if (components.unitCube()) { if (components.unitCube()) {

View file

@ -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.BoxComponent;
import org.geysermc.geyser.api.block.custom.component.CustomBlockComponents; 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.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.GeyserCustomBlockComponents;
import org.geysermc.geyser.level.block.GeyserCustomBlockData; import org.geysermc.geyser.level.block.GeyserCustomBlockData;
@ -110,7 +110,7 @@ public class CustomSkull {
private void addDefaultPermutation(List<CustomBlockPermutation> permutations) { private void addDefaultPermutation(List<CustomBlockPermutation> permutations) {
CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder() CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder()
.geometry("geometry.geyser.player_skull_hand") .geometry("geometry.geyser.player_skull_hand")
.rotation(new RotationComponent(0, 180, 0)) .transformation(new TransformationComponent(0, 180, 0))
.build(); .build();
String condition = String.format("query.block_property('%s') == 0 && query.block_property('%s') == 0", BITS_A_PROPERTY, BITS_B_PROPERTY); 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"}; String[] quadrantNames = {"a", "b", "c", "d"};
for (int quadrant = 0; quadrant < 4; quadrant++) { for (int quadrant = 0; quadrant < 4; quadrant++) {
RotationComponent rotation = new RotationComponent(0, ROTATIONS[quadrant], 0);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
int floorRotation = 4 * quadrant + i; int floorRotation = 4 * quadrant + i;
CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder() CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder()
.selectionBox(FLOOR_BOX) .selectionBox(FLOOR_BOX)
.collisionBox(FLOOR_BOX) .collisionBox(FLOOR_BOX)
.geometry("geometry.geyser.player_skull_floor_" + quadrantNames[i]) .geometry("geometry.geyser.player_skull_floor_" + quadrantNames[i])
.rotation(rotation) .transformation(new TransformationComponent(0, ROTATIONS[quadrant], 0))
.build(); .build();
int bitsA = (5 + floorRotation) % 7; int bitsA = (5 + floorRotation) % 7;
@ -141,12 +140,11 @@ public class CustomSkull {
private void addWallPermutations(List<CustomBlockPermutation> permutations) { private void addWallPermutations(List<CustomBlockPermutation> permutations) {
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
RotationComponent rotation = new RotationComponent(0, ROTATIONS[i], 0);
CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder() CustomBlockComponents components = new GeyserCustomBlockComponents.CustomBlockComponentsBuilder()
.selectionBox(WALL_BOX) .selectionBox(WALL_BOX)
.collisionBox(WALL_BOX) .collisionBox(WALL_BOX)
.geometry("geometry.geyser.player_skull_wall") .geometry("geometry.geyser.player_skull_wall")
.rotation(rotation) .transformation(new TransformationComponent(0, ROTATIONS[i], 0))
.build(); .build();
String condition = String.format("query.block_property('%s') == %d && query.block_property('%s') == %d", BITS_A_PROPERTY, i + 1, BITS_B_PROPERTY, 0); String condition = String.format("query.block_property('%s') == %d && query.block_property('%s') == %d", BITS_A_PROPERTY, i + 1, BITS_B_PROPERTY, 0);

View file

@ -28,6 +28,11 @@ package org.geysermc.geyser.util;
public class MathUtils { public class MathUtils {
public static final double SQRT_OF_TWO = Math.sqrt(2); 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) { public static float wrapDegrees(float degrees) {
degrees = degrees % 360.0f; degrees = degrees % 360.0f;
if (degrees < -180.0f) { if (degrees < -180.0f) {
@ -38,14 +43,51 @@ public class MathUtils {
return degrees; 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) { public static float wrapDegrees(double degrees) {
return wrapDegrees((float) 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) { public static int wrapDegreesToInt(float degrees) {
return (int) wrapDegrees(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 * Round the given float to the next whole number
* *