fix blockstate y-rotation direction and rotate top/bottom UVs without uvlock
Blockstate "y" rotations turned the geometry counter-clockwise while the faces were re-assigned clockwise (vanilla). Every east/west variant of an asymmetric block ended up mirrored on the wrong side of its cell: shelf mushrooms and ladders floated away from their support, stairs faced backwards. Rotate clockwise like vanilla, adjust element-rotation axes, and turn up/down face textures with the model unless uvlock is set. Edge-case test plugin: shelf mushroom (side + top view) and rotated-block scenes.
This commit is contained in:
1 parent
32afe08f03
commit
a99acad80c
2 files changed
+55
-5
No files matched your search
@@ -86,6 +86,12 @@ public final class ModelBaker {
|
||||
from = r[0];
|
||||
to = r[1];
|
||||
faces = rotateFacesY(faces);
|
||||
// Without uvlock the top/bottom textures turn with the model (vanilla); side faces already
|
||||
// keep their orientation through the face re-assignment. With uvlock they stay world-aligned.
|
||||
if (!variant.uvlock()) {
|
||||
faces[Direction.UP.ordinal()] = turned(faces[Direction.UP.ordinal()], 90);
|
||||
faces[Direction.DOWN.ordinal()] = turned(faces[Direction.DOWN.ordinal()], 90);
|
||||
}
|
||||
if (rotAxis >= 0) {
|
||||
rotOrigin = rotatePointY(rotOrigin);
|
||||
AxisRotation na = rotateAxisY(rotAxis);
|
||||
@@ -162,10 +168,16 @@ public final class ModelBaker {
|
||||
};
|
||||
}
|
||||
|
||||
/** The face with its texture lookup rotated by a further {@code deg} (90° steps). */
|
||||
private static Face turned(Face f, int deg) {
|
||||
if (f == null) return null;
|
||||
return new Face(f.texture, f.u1, f.v1, f.u2, f.v2, (f.rotation + deg) % 360, f.tintIndex);
|
||||
}
|
||||
|
||||
// --- 90-degree box rotations around the block center (0.5, 0.5, 0.5) ---
|
||||
|
||||
private double[][] rotateBoxY(double[] from, double[] to) {
|
||||
// (x,z) -> (z, 1-x): 90 deg clockwise viewed from above.
|
||||
// 90 deg clockwise viewed from above (vanilla), see rotatePointY.
|
||||
double[] c1 = rotatePointY(from);
|
||||
double[] c2 = rotatePointY(to);
|
||||
return minMax(c1, c2);
|
||||
@@ -178,8 +190,10 @@ public final class ModelBaker {
|
||||
}
|
||||
|
||||
private double[] rotatePointY(double[] p) {
|
||||
// Vanilla blockstate "y": clockwise seen from above (north -> east, south -> west), i.e. a rotation
|
||||
// by -90° about +Y: (dx, dz) -> (-dz, dx). Must match Direction.rotateY used for the faces.
|
||||
double x = p[0] - 0.5, z = p[2] - 0.5;
|
||||
return new double[] {0.5 + z, p[1], 0.5 - x};
|
||||
return new double[] {0.5 - z, p[1], 0.5 + x};
|
||||
}
|
||||
|
||||
private double[] rotatePointX(double[] p) {
|
||||
@@ -214,10 +228,10 @@ public final class ModelBaker {
|
||||
private record AxisRotation(int axis, boolean flip) {}
|
||||
|
||||
private AxisRotation rotateAxisY(int axis) {
|
||||
// Y rotation maps x<->z; the y axis is unchanged.
|
||||
// Clockwise Y rotation maps +x -> +z and +z -> -x; the y axis is unchanged.
|
||||
return switch (axis) {
|
||||
case 0 -> new AxisRotation(2, true); // x -> z
|
||||
case 2 -> new AxisRotation(0, false); // z -> x
|
||||
case 0 -> new AxisRotation(2, false); // x -> z
|
||||
case 2 -> new AxisRotation(0, true); // z -> -x
|
||||
default -> new AxisRotation(axis, false);
|
||||
};
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user