package com.mojang.math; import net.minecraft.Util; import java.util.stream.Collectors; import com.mojang.datafixers.util.Pair; import java.util.Arrays; import net.minecraft.core.FrontAndTop; import com.google.common.collect.Maps; import it.unimi.dsi.fastutil.booleans.BooleanArrayList; import it.unimi.dsi.fastutil.booleans.BooleanList; import javax.annotation.Nullable; import net.minecraft.core.Direction; import java.util.Map; import net.minecraft.util.StringRepresentable; public enum OctahedralGroup implements StringRepresentable { IDENTITY("identity", SymmetricGroup3.P123, false, false, false), ROT_180_FACE_XY("rot_180_face_xy", SymmetricGroup3.P123, true, true, false), ROT_180_FACE_XZ("rot_180_face_xz", SymmetricGroup3.P123, true, false, true), ROT_180_FACE_YZ("rot_180_face_yz", SymmetricGroup3.P123, false, true, true), ROT_120_NNN("rot_120_nnn", SymmetricGroup3.P231, false, false, false), ROT_120_NNP("rot_120_nnp", SymmetricGroup3.P312, true, false, true), ROT_120_NPN("rot_120_npn", SymmetricGroup3.P312, false, true, true), ROT_120_NPP("rot_120_npp", SymmetricGroup3.P231, true, false, true), ROT_120_PNN("rot_120_pnn", SymmetricGroup3.P312, true, true, false), ROT_120_PNP("rot_120_pnp", SymmetricGroup3.P231, true, true, false), ROT_120_PPN("rot_120_ppn", SymmetricGroup3.P231, false, true, true), ROT_120_PPP("rot_120_ppp", SymmetricGroup3.P312, false, false, false), ROT_180_EDGE_XY_NEG("rot_180_edge_xy_neg", SymmetricGroup3.P213, true, true, true), ROT_180_EDGE_XY_POS("rot_180_edge_xy_pos", SymmetricGroup3.P213, false, false, true), ROT_180_EDGE_XZ_NEG("rot_180_edge_xz_neg", SymmetricGroup3.P321, true, true, true), ROT_180_EDGE_XZ_POS("rot_180_edge_xz_pos", SymmetricGroup3.P321, false, true, false), ROT_180_EDGE_YZ_NEG("rot_180_edge_yz_neg", SymmetricGroup3.P132, true, true, true), ROT_180_EDGE_YZ_POS("rot_180_edge_yz_pos", SymmetricGroup3.P132, true, false, false), ROT_90_X_NEG("rot_90_x_neg", SymmetricGroup3.P132, false, false, true), ROT_90_X_POS("rot_90_x_pos", SymmetricGroup3.P132, false, true, false), ROT_90_Y_NEG("rot_90_y_neg", SymmetricGroup3.P321, true, false, false), ROT_90_Y_POS("rot_90_y_pos", SymmetricGroup3.P321, false, false, true), ROT_90_Z_NEG("rot_90_z_neg", SymmetricGroup3.P213, false, true, false), ROT_90_Z_POS("rot_90_z_pos", SymmetricGroup3.P213, true, false, false), INVERSION("inversion", SymmetricGroup3.P123, true, true, true), INVERT_X("invert_x", SymmetricGroup3.P123, true, false, false), INVERT_Y("invert_y", SymmetricGroup3.P123, false, true, false), INVERT_Z("invert_z", SymmetricGroup3.P123, false, false, true), ROT_60_REF_NNN("rot_60_ref_nnn", SymmetricGroup3.P312, true, true, true), ROT_60_REF_NNP("rot_60_ref_nnp", SymmetricGroup3.P231, true, false, false), ROT_60_REF_NPN("rot_60_ref_npn", SymmetricGroup3.P231, false, false, true), ROT_60_REF_NPP("rot_60_ref_npp", SymmetricGroup3.P312, false, false, true), ROT_60_REF_PNN("rot_60_ref_pnn", SymmetricGroup3.P231, false, true, false), ROT_60_REF_PNP("rot_60_ref_pnp", SymmetricGroup3.P312, true, false, false), ROT_60_REF_PPN("rot_60_ref_ppn", SymmetricGroup3.P312, false, true, false), ROT_60_REF_PPP("rot_60_ref_ppp", SymmetricGroup3.P231, true, true, true), SWAP_XY("swap_xy", SymmetricGroup3.P213, false, false, false), SWAP_YZ("swap_yz", SymmetricGroup3.P132, false, false, false), SWAP_XZ("swap_xz", SymmetricGroup3.P321, false, false, false), SWAP_NEG_XY("swap_neg_xy", SymmetricGroup3.P213, true, true, false), SWAP_NEG_YZ("swap_neg_yz", SymmetricGroup3.P132, false, true, true), SWAP_NEG_XZ("swap_neg_xz", SymmetricGroup3.P321, true, false, true), ROT_90_REF_X_NEG("rot_90_ref_x_neg", SymmetricGroup3.P132, true, false, true), ROT_90_REF_X_POS("rot_90_ref_x_pos", SymmetricGroup3.P132, true, true, false), ROT_90_REF_Y_NEG("rot_90_ref_y_neg", SymmetricGroup3.P321, true, true, false), ROT_90_REF_Y_POS("rot_90_ref_y_pos", SymmetricGroup3.P321, false, true, true), ROT_90_REF_Z_NEG("rot_90_ref_z_neg", SymmetricGroup3.P213, false, true, true), ROT_90_REF_Z_POS("rot_90_ref_z_pos", SymmetricGroup3.P213, true, false, true); private final Matrix3f transformation; private final String name; @Nullable private Map rotatedDirections; private final boolean invertX; private final boolean invertY; private final boolean invertZ; private final SymmetricGroup3 permutation; private static final OctahedralGroup[][] cayleyTable; private static final OctahedralGroup[] inverseTable; private OctahedralGroup(final String string3, final SymmetricGroup3 e, final boolean boolean5, final boolean boolean6, final boolean boolean7) { this.name = string3; this.invertX = boolean5; this.invertY = boolean6; this.invertZ = boolean7; this.permutation = e; this.transformation = new Matrix3f(); this.transformation.m00 = (boolean5 ? -1.0f : 1.0f); this.transformation.m11 = (boolean6 ? -1.0f : 1.0f); this.transformation.m22 = (boolean7 ? -1.0f : 1.0f); this.transformation.mul(e.transformation()); } private BooleanList packInversions() { return (BooleanList)new BooleanArrayList(new boolean[] { this.invertX, this.invertY, this.invertZ }); } public OctahedralGroup compose(final OctahedralGroup c) { return OctahedralGroup.cayleyTable[this.ordinal()][c.ordinal()]; } @Override public String toString() { return this.name; } @Override public String getSerializedName() { return this.name; } public Direction rotate(final Direction fz) { if (this.rotatedDirections == null) { this.rotatedDirections = Maps.newEnumMap(Direction.class); for (final Direction fz2 : Direction.values()) { final Direction.Axis a7 = fz2.getAxis(); final Direction.AxisDirection b8 = fz2.getAxisDirection(); final Direction.Axis a8 = Direction.Axis.values()[this.permutation.permutation(a7.ordinal())]; final Direction.AxisDirection b9 = this.inverts(a8) ? b8.opposite() : b8; final Direction fz3 = Direction.fromAxisAndDirection(a8, b9); this.rotatedDirections.put(fz2, fz3); } } return this.rotatedDirections.get(fz); } public boolean inverts(final Direction.Axis a) { switch (a) { case X: { return this.invertX; } case Y: { return this.invertY; } default: { return this.invertZ; } } } public FrontAndTop rotate(final FrontAndTop gb) { return FrontAndTop.fromFrontAndTop(this.rotate(gb.front()), this.rotate(gb.top())); } static { final Map, OctahedralGroup> map2; final OctahedralGroup[] array; int length; int i = 0; OctahedralGroup c3; final OctahedralGroup[] array2; int length2; int j = 0; OctahedralGroup c4; BooleanList booleanList11; BooleanList booleanList12; SymmetricGroup3 e13; BooleanArrayList booleanArrayList14; int integer2; cayleyTable = Util.make(new OctahedralGroup[values().length][values().length], arr -> { map2 = Arrays.stream(values()).collect(Collectors.toMap(c -> Pair.of(c.permutation, c.packInversions()), c -> c)); values(); for (length = array.length; i < length; ++i) { c3 = array[i]; values(); for (length2 = array2.length; j < length2; ++j) { c4 = array2[j]; booleanList11 = c3.packInversions(); booleanList12 = c4.packInversions(); e13 = c4.permutation.compose(c3.permutation); booleanArrayList14 = new BooleanArrayList(3); for (integer2 = 0; integer2 < 3; ++integer2) { booleanArrayList14.add(booleanList11.getBoolean(integer2) ^ booleanList12.getBoolean(c3.permutation.permutation(integer2))); } arr[c3.ordinal()][c4.ordinal()] = map2.get(Pair.of(e13, booleanArrayList14)); } } return; }); inverseTable = Arrays.stream(values()).map(c -> Arrays.stream(values()).filter(c2 -> c.compose(c2) == OctahedralGroup.IDENTITY).findAny().get()).toArray(OctahedralGroup[]::new); } }