2025-11-24 22:52:51 +03:00

168 lines
6.1 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* org.apache.commons.lang3.tuple.Triple
* org.joml.Math
* org.joml.Matrix3f
* org.joml.Matrix3fc
* org.joml.Matrix4f
* org.joml.Matrix4fc
* org.joml.Quaternionf
* org.joml.Quaternionfc
* org.joml.Vector3f
*/
package com.mojang.math;
import com.mojang.math.GivensParameters;
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.Matrix4fc;
import org.joml.Quaternionf;
import org.joml.Quaternionfc;
import org.joml.Vector3f;
public class MatrixUtil {
private static final float G = 3.0f + 2.0f * Math.sqrt((float)2.0f);
private static final GivensParameters PI_4 = GivensParameters.fromPositiveAngle(0.7853982f);
private MatrixUtil() {
}
public static Matrix4f mulComponentWise(Matrix4f m, float factor) {
return m.set(m.m00() * factor, m.m01() * factor, m.m02() * factor, m.m03() * factor, m.m10() * factor, m.m11() * factor, m.m12() * factor, m.m13() * factor, m.m20() * factor, m.m21() * factor, m.m22() * factor, m.m23() * factor, m.m30() * factor, m.m31() * factor, m.m32() * factor, m.m33() * factor);
}
private static GivensParameters approxGivensQuat(float a11, float a12, float a22) {
float sh = a12;
float ch = 2.0f * (a11 - a22);
if (G * sh * sh < ch * ch) {
return GivensParameters.fromUnnormalized(sh, ch);
}
return PI_4;
}
private static GivensParameters qrGivensQuat(float a1, float a2) {
float p = (float)java.lang.Math.hypot(a1, a2);
float sh = p > 1.0E-6f ? a2 : 0.0f;
float ch = Math.abs((float)a1) + Math.max((float)p, (float)1.0E-6f);
if (a1 < 0.0f) {
float f = sh;
sh = ch;
ch = f;
}
return GivensParameters.fromUnnormalized(sh, ch);
}
private static void similarityTransform(Matrix3f a, Matrix3f q) {
a.mul((Matrix3fc)q);
q.transpose();
q.mul((Matrix3fc)a);
a.set((Matrix3fc)q);
}
private static void stepJacobi(Matrix3f m, Matrix3f tmpMat, Quaternionf tmpQ, Quaternionf output) {
Quaternionf qt;
GivensParameters p;
if (m.m01 * m.m01 + m.m10 * m.m10 > 1.0E-6f) {
p = MatrixUtil.approxGivensQuat(m.m00, 0.5f * (m.m01 + m.m10), m.m11);
qt = p.aroundZ(tmpQ);
output.mul((Quaternionfc)qt);
p.aroundZ(tmpMat);
MatrixUtil.similarityTransform(m, tmpMat);
}
if (m.m02 * m.m02 + m.m20 * m.m20 > 1.0E-6f) {
p = MatrixUtil.approxGivensQuat(m.m00, 0.5f * (m.m02 + m.m20), m.m22).inverse();
qt = p.aroundY(tmpQ);
output.mul((Quaternionfc)qt);
p.aroundY(tmpMat);
MatrixUtil.similarityTransform(m, tmpMat);
}
if (m.m12 * m.m12 + m.m21 * m.m21 > 1.0E-6f) {
p = MatrixUtil.approxGivensQuat(m.m11, 0.5f * (m.m12 + m.m21), m.m22);
qt = p.aroundX(tmpQ);
output.mul((Quaternionfc)qt);
p.aroundX(tmpMat);
MatrixUtil.similarityTransform(m, tmpMat);
}
}
public static Quaternionf eigenvalueJacobi(Matrix3f inOut, int steps) {
Quaternionf v = new Quaternionf();
Matrix3f scratchMat = new Matrix3f();
Quaternionf scratchQ = new Quaternionf();
for (int i = 0; i < steps; ++i) {
MatrixUtil.stepJacobi(inOut, scratchMat, scratchQ, v);
}
v.normalize();
return v;
}
public static Triple<Quaternionf, Vector3f, Quaternionf> svdDecompose(Matrix3f matrix) {
Matrix3f b = new Matrix3f((Matrix3fc)matrix);
b.transpose();
b.mul((Matrix3fc)matrix);
Quaternionf v = MatrixUtil.eigenvalueJacobi(b, 5);
float columnScaleSquare0 = b.m00;
float columnScaleSquare1 = b.m11;
boolean zeroColumn0 = (double)columnScaleSquare0 < 1.0E-6;
boolean zeroColumn1 = (double)columnScaleSquare1 < 1.0E-6;
Matrix3f scratch = b;
Matrix3f u012s = matrix.rotate((Quaternionfc)v);
Quaternionf u = new Quaternionf();
Quaternionf tmpQ = new Quaternionf();
GivensParameters p = zeroColumn0 ? MatrixUtil.qrGivensQuat(u012s.m11, -u012s.m10) : MatrixUtil.qrGivensQuat(u012s.m00, u012s.m01);
Quaternionf qt0 = p.aroundZ(tmpQ);
Matrix3f u12s = p.aroundZ(scratch);
u.mul((Quaternionfc)qt0);
u12s.transpose().mul((Matrix3fc)u012s);
scratch = u012s;
p = zeroColumn0 ? MatrixUtil.qrGivensQuat(u12s.m22, -u12s.m20) : MatrixUtil.qrGivensQuat(u12s.m00, u12s.m02);
p = p.inverse();
Quaternionf qt1 = p.aroundY(tmpQ);
Matrix3f u2s = p.aroundY(scratch);
u.mul((Quaternionfc)qt1);
u2s.transpose().mul((Matrix3fc)u12s);
scratch = u12s;
p = zeroColumn1 ? MatrixUtil.qrGivensQuat(u2s.m22, -u2s.m21) : MatrixUtil.qrGivensQuat(u2s.m11, u2s.m12);
Quaternionf qt2 = p.aroundX(tmpQ);
Matrix3f s = p.aroundX(scratch);
u.mul((Quaternionfc)qt2);
s.transpose().mul((Matrix3fc)u2s);
Vector3f scale = new Vector3f(s.m00, s.m11, s.m22);
return Triple.of((Object)u, (Object)scale, (Object)v.conjugate());
}
private static boolean checkPropertyRaw(Matrix4fc matrix, int property) {
return (matrix.properties() & property) != 0;
}
public static boolean checkProperty(Matrix4fc matrix, int property) {
if (MatrixUtil.checkPropertyRaw(matrix, property)) {
return true;
}
if (matrix instanceof Matrix4f) {
Matrix4f mutableMatrix = (Matrix4f)matrix;
mutableMatrix.determineProperties();
return MatrixUtil.checkPropertyRaw(matrix, property);
}
return false;
}
public static boolean isIdentity(Matrix4fc matrix) {
return MatrixUtil.checkProperty(matrix, 4);
}
public static boolean isPureTranslation(Matrix4fc matrix) {
return MatrixUtil.checkProperty(matrix, 8);
}
public static boolean isOrthonormal(Matrix4fc matrix) {
return MatrixUtil.checkProperty(matrix, 16);
}
}