Initial Commit

This commit is contained in:
richard committed 2026-11-13 22:25:04 +01:00
1 parent 377b32db6e
commit 2d9a5eecba
14134 files changed
+1160982

No files matched your search

@@ -0,0 +1,38 @@
package com.mojang.math;
import org.joml.Quaternionf;
import org.joml.Vector3f;
@FunctionalInterface
public interface Axis {
Axis XN = (p_254437_) -> {
return (new Quaternionf()).rotationX(-p_254437_);
};
Axis XP = (p_254466_) -> {
return (new Quaternionf()).rotationX(p_254466_);
};
Axis YN = (p_254442_) -> {
return (new Quaternionf()).rotationY(-p_254442_);
};
Axis YP = (p_254103_) -> {
return (new Quaternionf()).rotationY(p_254103_);
};
Axis ZN = (p_254110_) -> {
return (new Quaternionf()).rotationZ(-p_254110_);
};
Axis ZP = (p_253997_) -> {
return (new Quaternionf()).rotationZ(p_253997_);
};
static Axis of(Vector3f p_254398_) {
return (p_254401_) -> {
return (new Quaternionf()).rotationAxis(p_254401_, p_254398_);
};
}
Quaternionf rotation(float p_254545_);
default Quaternionf rotationDegrees(float p_253800_) {
return this.rotation(p_253800_ * ((float)Math.PI / 180F));
}
}
@@ -0,0 +1,8 @@
package com.mojang.math;
public class Constants {
public static final float PI = (float)Math.PI;
public static final float RAD_TO_DEG = (180F / (float)Math.PI);
public static final float DEG_TO_RAD = ((float)Math.PI / 180F);
public static final float EPSILON = 1.0E-6F;
}
@@ -0,0 +1,52 @@
package com.mojang.math;
import com.google.common.annotations.VisibleForTesting;
import it.unimi.dsi.fastutil.ints.IntIterator;
import java.util.NoSuchElementException;
public class Divisor implements IntIterator {
private final int denominator;
private final int quotient;
private final int mod;
private int returnedParts;
private int remainder;
public Divisor(int pNumerator, int pDenominator) {
this.denominator = pDenominator;
if (pDenominator > 0) {
this.quotient = pNumerator / pDenominator;
this.mod = pNumerator % pDenominator;
} else {
this.quotient = 0;
this.mod = 0;
}
}
public boolean hasNext() {
return this.returnedParts < this.denominator;
}
public int nextInt() {
if (!this.hasNext()) {
throw new NoSuchElementException();
} else {
int i = this.quotient;
this.remainder += this.mod;
if (this.remainder >= this.denominator) {
this.remainder -= this.denominator;
++i;
}
++this.returnedParts;
return i;
}
}
@VisibleForTesting
public static Iterable<Integer> asIterable(int pNumerator, int pDenominator) {
return () -> {
return new Divisor(pNumerator, pDenominator);
};
}
}
@@ -0,0 +1,13 @@
package com.mojang.math;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
@Nonnull
@TypeQualifierDefault({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldsAreNonnullByDefault {
}
@@ -0,0 +1,87 @@
package com.mojang.math;
import org.joml.Math;
import org.joml.Matrix3f;
import org.joml.Quaternionf;
public record GivensParameters(float sinHalf, float cosHalf) {
public static GivensParameters fromUnnormalized(float pSinHalf, float pCosHalf) {
float f = Math.invsqrt(pSinHalf * pSinHalf + pCosHalf * pCosHalf);
return new GivensParameters(f * pSinHalf, f * pCosHalf);
}
public static GivensParameters fromPositiveAngle(float pAngle) {
float f = Math.sin(pAngle / 2.0F);
float f1 = Math.cosFromSin(f, pAngle / 2.0F);
return new GivensParameters(f, f1);
}
public GivensParameters inverse() {
return new GivensParameters(-this.sinHalf, this.cosHalf);
}
public Quaternionf aroundX(Quaternionf pQuaternion) {
return pQuaternion.set(this.sinHalf, 0.0F, 0.0F, this.cosHalf);
}
public Quaternionf aroundY(Quaternionf pQuaternion) {
return pQuaternion.set(0.0F, this.sinHalf, 0.0F, this.cosHalf);
}
public Quaternionf aroundZ(Quaternionf pQuaternion) {
return pQuaternion.set(0.0F, 0.0F, this.sinHalf, this.cosHalf);
}
public float cos() {
return this.cosHalf * this.cosHalf - this.sinHalf * this.sinHalf;
}
public float sin() {
return 2.0F * this.sinHalf * this.cosHalf;
}
public Matrix3f aroundX(Matrix3f pMatrix) {
pMatrix.m01 = 0.0F;
pMatrix.m02 = 0.0F;
pMatrix.m10 = 0.0F;
pMatrix.m20 = 0.0F;
float f = this.cos();
float f1 = this.sin();
pMatrix.m11 = f;
pMatrix.m22 = f;
pMatrix.m12 = f1;
pMatrix.m21 = -f1;
pMatrix.m00 = 1.0F;
return pMatrix;
}
public Matrix3f aroundY(Matrix3f pMatrix) {
pMatrix.m01 = 0.0F;
pMatrix.m10 = 0.0F;
pMatrix.m12 = 0.0F;
pMatrix.m21 = 0.0F;
float f = this.cos();
float f1 = this.sin();
pMatrix.m00 = f;
pMatrix.m22 = f;
pMatrix.m02 = -f1;
pMatrix.m20 = f1;
pMatrix.m11 = 1.0F;
return pMatrix;
}
public Matrix3f aroundZ(Matrix3f pMatrix) {
pMatrix.m02 = 0.0F;
pMatrix.m12 = 0.0F;
pMatrix.m20 = 0.0F;
pMatrix.m21 = 0.0F;
float f = this.cos();
float f1 = this.sin();
pMatrix.m00 = f;
pMatrix.m11 = f;
pMatrix.m01 = f1;
pMatrix.m10 = -f1;
pMatrix.m22 = 1.0F;
return pMatrix;
}
}
@@ -0,0 +1,134 @@
package com.mojang.math;
import org.apache.commons.lang3.tuple.Triple;
import org.joml.Math;
import org.joml.Matrix3f;
import org.joml.Matrix3fc;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
public class MatrixUtil {
private static final float G = 3.0F + 2.0F * Math.sqrt(2.0F);
private static final GivensParameters PI_4 = GivensParameters.fromPositiveAngle(((float)java.lang.Math.PI / 4F));
private MatrixUtil() {
}
public static Matrix4f mulComponentWise(Matrix4f pMatrix, float pScalar) {
return pMatrix.set(pMatrix.m00() * pScalar, pMatrix.m01() * pScalar, pMatrix.m02() * pScalar, pMatrix.m03() * pScalar, pMatrix.m10() * pScalar, pMatrix.m11() * pScalar, pMatrix.m12() * pScalar, pMatrix.m13() * pScalar, pMatrix.m20() * pScalar, pMatrix.m21() * pScalar, pMatrix.m22() * pScalar, pMatrix.m23() * pScalar, pMatrix.m30() * pScalar, pMatrix.m31() * pScalar, pMatrix.m32() * pScalar, pMatrix.m33() * pScalar);
}
private static GivensParameters approxGivensQuat(float p_276275_, float p_276276_, float p_276282_) {
float f = 2.0F * (p_276275_ - p_276282_);
return G * p_276276_ * p_276276_ < f * f ? GivensParameters.fromUnnormalized(p_276276_, f) : PI_4;
}
private static GivensParameters qrGivensQuat(float p_253897_, float p_254413_) {
float f = (float)java.lang.Math.hypot((double)p_253897_, (double)p_254413_);
float f1 = f > 1.0E-6F ? p_254413_ : 0.0F;
float f2 = Math.abs(p_253897_) + Math.max(f, 1.0E-6F);
if (p_253897_ < 0.0F) {
float f3 = f1;
f1 = f2;
f2 = f3;
}
return GivensParameters.fromUnnormalized(f1, f2);
}
private static void similarityTransform(Matrix3f p_276319_, Matrix3f p_276263_) {
p_276319_.mul(p_276263_);
p_276263_.transpose();
p_276263_.mul(p_276319_);
p_276319_.set((Matrix3fc)p_276263_);
}
private static void stepJacobi(Matrix3f p_276262_, Matrix3f p_276279_, Quaternionf p_276314_, Quaternionf p_276299_) {
if (p_276262_.m01 * p_276262_.m01 + p_276262_.m10 * p_276262_.m10 > 1.0E-6F) {
GivensParameters givensparameters = approxGivensQuat(p_276262_.m00, 0.5F * (p_276262_.m01 + p_276262_.m10), p_276262_.m11);
Quaternionf quaternionf = givensparameters.aroundZ(p_276314_);
p_276299_.mul(quaternionf);
givensparameters.aroundZ(p_276279_);
similarityTransform(p_276262_, p_276279_);
}
if (p_276262_.m02 * p_276262_.m02 + p_276262_.m20 * p_276262_.m20 > 1.0E-6F) {
GivensParameters givensparameters1 = approxGivensQuat(p_276262_.m00, 0.5F * (p_276262_.m02 + p_276262_.m20), p_276262_.m22).inverse();
Quaternionf quaternionf1 = givensparameters1.aroundY(p_276314_);
p_276299_.mul(quaternionf1);
givensparameters1.aroundY(p_276279_);
similarityTransform(p_276262_, p_276279_);
}
if (p_276262_.m12 * p_276262_.m12 + p_276262_.m21 * p_276262_.m21 > 1.0E-6F) {
GivensParameters givensparameters2 = approxGivensQuat(p_276262_.m11, 0.5F * (p_276262_.m12 + p_276262_.m21), p_276262_.m22);
Quaternionf quaternionf2 = givensparameters2.aroundX(p_276314_);
p_276299_.mul(quaternionf2);
givensparameters2.aroundX(p_276279_);
similarityTransform(p_276262_, p_276279_);
}
}
public static Quaternionf eigenvalueJacobi(Matrix3f p_276278_, int p_276269_) {
Quaternionf quaternionf = new Quaternionf();
Matrix3f matrix3f = new Matrix3f();
Quaternionf quaternionf1 = new Quaternionf();
for(int i = 0; i < p_276269_; ++i) {
stepJacobi(p_276278_, matrix3f, quaternionf1, quaternionf);
}
quaternionf.normalize();
return quaternionf;
}
public static Triple<Quaternionf, Vector3f, Quaternionf> svdDecompose(Matrix3f pMatrix) {
Matrix3f matrix3f = new Matrix3f(pMatrix);
matrix3f.transpose();
matrix3f.mul(pMatrix);
Quaternionf quaternionf = eigenvalueJacobi(matrix3f, 5);
float f = matrix3f.m00;
float f1 = matrix3f.m11;
boolean flag = (double)f < 1.0E-6D;
boolean flag1 = (double)f1 < 1.0E-6D;
Matrix3f matrix3f1 = pMatrix.rotate(quaternionf);
Quaternionf quaternionf1 = new Quaternionf();
Quaternionf quaternionf2 = new Quaternionf();
GivensParameters givensparameters;
if (flag) {
givensparameters = qrGivensQuat(matrix3f1.m11, -matrix3f1.m10);
} else {
givensparameters = qrGivensQuat(matrix3f1.m00, matrix3f1.m01);
}
Quaternionf quaternionf3 = givensparameters.aroundZ(quaternionf2);
Matrix3f matrix3f2 = givensparameters.aroundZ(matrix3f);
quaternionf1.mul(quaternionf3);
matrix3f2.transpose().mul(matrix3f1);
if (flag) {
givensparameters = qrGivensQuat(matrix3f2.m22, -matrix3f2.m20);
} else {
givensparameters = qrGivensQuat(matrix3f2.m00, matrix3f2.m02);
}
givensparameters = givensparameters.inverse();
Quaternionf quaternionf4 = givensparameters.aroundY(quaternionf2);
Matrix3f matrix3f3 = givensparameters.aroundY(matrix3f1);
quaternionf1.mul(quaternionf4);
matrix3f3.transpose().mul(matrix3f2);
if (flag1) {
givensparameters = qrGivensQuat(matrix3f3.m22, -matrix3f3.m21);
} else {
givensparameters = qrGivensQuat(matrix3f3.m11, matrix3f3.m12);
}
Quaternionf quaternionf5 = givensparameters.aroundX(quaternionf2);
Matrix3f matrix3f4 = givensparameters.aroundX(matrix3f2);
quaternionf1.mul(quaternionf5);
matrix3f4.transpose().mul(matrix3f3);
Vector3f vector3f = new Vector3f(matrix3f4.m00, matrix3f4.m11, matrix3f4.m22);
return Triple.of(quaternionf1, vector3f, quaternionf.conjugate());
}
}
@@ -0,0 +1,13 @@
package com.mojang.math;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import javax.annotation.Nonnull;
import javax.annotation.meta.TypeQualifierDefault;
@Nonnull
@TypeQualifierDefault({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodsReturnNonnullByDefault {
}
@@ -0,0 +1,173 @@
package com.mojang.math;
import com.google.common.collect.Maps;
import com.mojang.datafixers.util.Pair;
import it.unimi.dsi.fastutil.booleans.BooleanArrayList;
import it.unimi.dsi.fastutil.booleans.BooleanList;
import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import net.minecraft.Util;
import net.minecraft.core.Direction;
import net.minecraft.core.FrontAndTop;
import net.minecraft.util.StringRepresentable;
import org.joml.Matrix3f;
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<Direction, Direction> rotatedDirections;
private final boolean invertX;
private final boolean invertY;
private final boolean invertZ;
private final SymmetricGroup3 permutation;
private static final OctahedralGroup[][] cayleyTable = Util.make(new OctahedralGroup[values().length][values().length], (p_56533_) -> {
Map<Pair<SymmetricGroup3, BooleanList>, OctahedralGroup> map = Arrays.stream(values()).collect(Collectors.toMap((p_174952_) -> {
return Pair.of(p_174952_.permutation, p_174952_.packInversions());
}, (p_174950_) -> {
return p_174950_;
}));
for(OctahedralGroup octahedralgroup : values()) {
for(OctahedralGroup octahedralgroup1 : values()) {
BooleanList booleanlist = octahedralgroup.packInversions();
BooleanList booleanlist1 = octahedralgroup1.packInversions();
SymmetricGroup3 symmetricgroup3 = octahedralgroup1.permutation.compose(octahedralgroup.permutation);
BooleanArrayList booleanarraylist = new BooleanArrayList(3);
for(int i = 0; i < 3; ++i) {
booleanarraylist.add(booleanlist.getBoolean(i) ^ booleanlist1.getBoolean(octahedralgroup.permutation.permutation(i)));
}
p_56533_[octahedralgroup.ordinal()][octahedralgroup1.ordinal()] = map.get(Pair.of(symmetricgroup3, booleanarraylist));
}
}
});
private static final OctahedralGroup[] inverseTable = Arrays.stream(values()).map((p_56536_) -> {
return Arrays.stream(values()).filter((p_174947_) -> {
return p_56536_.compose(p_174947_) == IDENTITY;
}).findAny().get();
}).toArray((p_56520_) -> {
return new OctahedralGroup[p_56520_];
});
private OctahedralGroup(String pName, SymmetricGroup3 pPermutation, boolean pInvertX, boolean pInvertY, boolean pInvertZ) {
this.name = pName;
this.invertX = pInvertX;
this.invertY = pInvertY;
this.invertZ = pInvertZ;
this.permutation = pPermutation;
this.transformation = (new Matrix3f()).scaling(pInvertX ? -1.0F : 1.0F, pInvertY ? -1.0F : 1.0F, pInvertZ ? -1.0F : 1.0F);
this.transformation.mul(pPermutation.transformation());
}
private BooleanList packInversions() {
return new BooleanArrayList(new boolean[]{this.invertX, this.invertY, this.invertZ});
}
public OctahedralGroup compose(OctahedralGroup pOther) {
return cayleyTable[this.ordinal()][pOther.ordinal()];
}
public OctahedralGroup inverse() {
return inverseTable[this.ordinal()];
}
public Matrix3f transformation() {
return new Matrix3f(this.transformation);
}
public String toString() {
return this.name;
}
public String getSerializedName() {
return this.name;
}
public Direction rotate(Direction pDirection) {
if (this.rotatedDirections == null) {
this.rotatedDirections = Maps.newEnumMap(Direction.class);
Direction.Axis[] adirection$axis = Direction.Axis.values();
for(Direction direction : Direction.values()) {
Direction.Axis direction$axis = direction.getAxis();
Direction.AxisDirection direction$axisdirection = direction.getAxisDirection();
Direction.Axis direction$axis1 = adirection$axis[this.permutation.permutation(direction$axis.ordinal())];
Direction.AxisDirection direction$axisdirection1 = this.inverts(direction$axis1) ? direction$axisdirection.opposite() : direction$axisdirection;
Direction direction1 = Direction.fromAxisAndDirection(direction$axis1, direction$axisdirection1);
this.rotatedDirections.put(direction, direction1);
}
}
return this.rotatedDirections.get(pDirection);
}
public boolean inverts(Direction.Axis pAxis) {
switch (pAxis) {
case X:
return this.invertX;
case Y:
return this.invertY;
case Z:
default:
return this.invertZ;
}
}
public FrontAndTop rotate(FrontAndTop pFrontAndTop) {
return FrontAndTop.fromFrontAndTop(this.rotate(pFrontAndTop.front()), this.rotate(pFrontAndTop.top()));
}
}
@@ -0,0 +1,58 @@
package com.mojang.math;
import java.util.Arrays;
import net.minecraft.Util;
import org.joml.Matrix3f;
/**
* The symmetric group S3, also known as all the permutation orders of three elements.
*/
public enum SymmetricGroup3 {
P123(0, 1, 2),
P213(1, 0, 2),
P132(0, 2, 1),
P231(1, 2, 0),
P312(2, 0, 1),
P321(2, 1, 0);
private final int[] permutation;
private final Matrix3f transformation;
private static final int ORDER = 3;
private static final SymmetricGroup3[][] cayleyTable = Util.make(new SymmetricGroup3[values().length][values().length], (p_109188_) -> {
for(SymmetricGroup3 symmetricgroup3 : values()) {
for(SymmetricGroup3 symmetricgroup31 : values()) {
int[] aint = new int[3];
for(int i = 0; i < 3; ++i) {
aint[i] = symmetricgroup3.permutation[symmetricgroup31.permutation[i]];
}
SymmetricGroup3 symmetricgroup32 = Arrays.stream(values()).filter((p_175577_) -> {
return Arrays.equals(p_175577_.permutation, aint);
}).findFirst().get();
p_109188_[symmetricgroup3.ordinal()][symmetricgroup31.ordinal()] = symmetricgroup32;
}
}
});
private SymmetricGroup3(int pFirst, int pSecond, int pThird) {
this.permutation = new int[]{pFirst, pSecond, pThird};
this.transformation = new Matrix3f();
this.transformation.set(this.permutation(0), 0, 1.0F);
this.transformation.set(this.permutation(1), 1, 1.0F);
this.transformation.set(this.permutation(2), 2, 1.0F);
}
public SymmetricGroup3 compose(SymmetricGroup3 pOther) {
return cayleyTable[this.ordinal()][pOther.ordinal()];
}
public int permutation(int pElement) {
return this.permutation[pElement];
}
public Matrix3f transformation() {
return this.transformation;
}
}
@@ -0,0 +1,191 @@
package com.mojang.math;
import com.mojang.datafixers.util.Either;
import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import java.util.Objects;
import javax.annotation.Nullable;
import net.minecraft.Util;
import net.minecraft.util.ExtraCodecs;
import org.apache.commons.lang3.tuple.Triple;
import org.joml.Matrix3f;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.joml.Vector3fc;
public final class Transformation implements net.minecraftforge.common.extensions.IForgeTransformation {
private final Matrix4f matrix;
public static final Codec<Transformation> CODEC = RecordCodecBuilder.create((p_269604_) -> {
return p_269604_.group(ExtraCodecs.VECTOR3F.fieldOf("translation").forGetter((p_269599_) -> {
return p_269599_.translation;
}), ExtraCodecs.QUATERNIONF.fieldOf("left_rotation").forGetter((p_269600_) -> {
return p_269600_.leftRotation;
}), ExtraCodecs.VECTOR3F.fieldOf("scale").forGetter((p_269603_) -> {
return p_269603_.scale;
}), ExtraCodecs.QUATERNIONF.fieldOf("right_rotation").forGetter((p_269598_) -> {
return p_269598_.rightRotation;
})).apply(p_269604_, Transformation::new);
});
public static final Codec<Transformation> EXTENDED_CODEC = Codec.either(CODEC, ExtraCodecs.MATRIX4F.xmap(Transformation::new, Transformation::getMatrix)).xmap((p_269605_) -> {
return p_269605_.map((p_269601_) -> {
return p_269601_;
}, (p_269602_) -> {
return p_269602_;
});
}, Either::left);
private boolean decomposed;
@Nullable
private Vector3f translation;
@Nullable
private Quaternionf leftRotation;
@Nullable
private Vector3f scale;
@Nullable
private Quaternionf rightRotation;
private static final Transformation IDENTITY = Util.make(() -> {
Transformation transformation = new Transformation(new Matrix4f());
transformation.translation = new Vector3f();
transformation.leftRotation = new Quaternionf();
transformation.scale = new Vector3f(1.0F, 1.0F, 1.0F);
transformation.rightRotation = new Quaternionf();
transformation.decomposed = true;
return transformation;
});
public Transformation(@Nullable Matrix4f p_253689_) {
if (p_253689_ == null) {
this.matrix = new Matrix4f();
} else {
this.matrix = p_253689_;
}
}
public Transformation(@Nullable Vector3f p_253831_, @Nullable Quaternionf p_253846_, @Nullable Vector3f p_254502_, @Nullable Quaternionf p_253912_) {
this.matrix = compose(p_253831_, p_253846_, p_254502_, p_253912_);
this.translation = p_253831_ != null ? p_253831_ : new Vector3f();
this.leftRotation = p_253846_ != null ? p_253846_ : new Quaternionf();
this.scale = p_254502_ != null ? p_254502_ : new Vector3f(1.0F, 1.0F, 1.0F);
this.rightRotation = p_253912_ != null ? p_253912_ : new Quaternionf();
this.decomposed = true;
}
public static Transformation identity() {
return IDENTITY;
}
public Transformation compose(Transformation pOther) {
Matrix4f matrix4f = this.getMatrix();
matrix4f.mul(pOther.getMatrix());
return new Transformation(matrix4f);
}
@Nullable
public Transformation inverse() {
if (this == IDENTITY) {
return this;
} else {
Matrix4f matrix4f = this.getMatrix().invert();
return matrix4f.isFinite() ? new Transformation(matrix4f) : null;
}
}
private void ensureDecomposed() {
if (!this.decomposed) {
float f = 1.0F / this.matrix.m33();
Triple<Quaternionf, Vector3f, Quaternionf> triple = MatrixUtil.svdDecompose((new Matrix3f(this.matrix)).scale(f));
this.translation = this.matrix.getTranslation(new Vector3f()).mul(f);
this.leftRotation = new Quaternionf(triple.getLeft());
this.scale = new Vector3f(triple.getMiddle());
this.rightRotation = new Quaternionf(triple.getRight());
this.decomposed = true;
}
}
private static Matrix4f compose(@Nullable Vector3f pTranslation, @Nullable Quaternionf pLeftRotation, @Nullable Vector3f pScale, @Nullable Quaternionf pRightRotation) {
Matrix4f matrix4f = new Matrix4f();
if (pTranslation != null) {
matrix4f.translation(pTranslation);
}
if (pLeftRotation != null) {
matrix4f.rotate(pLeftRotation);
}
if (pScale != null) {
matrix4f.scale(pScale);
}
if (pRightRotation != null) {
matrix4f.rotate(pRightRotation);
}
return matrix4f;
}
public Matrix4f getMatrix() {
return new Matrix4f(this.matrix);
}
public Vector3f getTranslation() {
this.ensureDecomposed();
return new Vector3f((Vector3fc)this.translation);
}
public Quaternionf getLeftRotation() {
this.ensureDecomposed();
return new Quaternionf(this.leftRotation);
}
public Vector3f getScale() {
this.ensureDecomposed();
return new Vector3f((Vector3fc)this.scale);
}
public Quaternionf getRightRotation() {
this.ensureDecomposed();
return new Quaternionf(this.rightRotation);
}
public boolean equals(Object pOther) {
if (this == pOther) {
return true;
} else if (pOther != null && this.getClass() == pOther.getClass()) {
Transformation transformation = (Transformation)pOther;
return Objects.equals(this.matrix, transformation.matrix);
} else {
return false;
}
}
public int hashCode() {
return Objects.hash(this.matrix);
}
private Matrix3f normalTransform = null;
public Matrix3f getNormalMatrix() {
checkNormalTransform();
return normalTransform;
}
private void checkNormalTransform() {
if (normalTransform == null) {
normalTransform = new Matrix3f(matrix);
normalTransform.invert();
normalTransform.transpose();
}
}
public Transformation slerp(Transformation pTransformation, float pDelta) {
Vector3f vector3f = this.getTranslation();
Quaternionf quaternionf = this.getLeftRotation();
Vector3f vector3f1 = this.getScale();
Quaternionf quaternionf1 = this.getRightRotation();
vector3f.lerp(pTransformation.getTranslation(), pDelta);
quaternionf.slerp(pTransformation.getLeftRotation(), pDelta);
vector3f1.lerp(pTransformation.getScale(), pDelta);
quaternionf1.slerp(pTransformation.getRightRotation(), pDelta);
return new Transformation(vector3f, quaternionf, vector3f1, quaternionf1);
}
}
@@ -0,0 +1,6 @@
@ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault
@FieldsAreNonnullByDefault
package com.mojang.math;
import javax.annotation.ParametersAreNonnullByDefault;