minecraft-source/src/com/mojang/math/Transformation.java

139 lines
4.2 KiB
Java
Raw Normal View History

2020-07-22 06:25:47 +01:00
package com.mojang.math;
import net.minecraft.Util;
import java.util.Objects;
import org.apache.commons.lang3.tuple.Triple;
import com.mojang.datafixers.util.Pair;
import javax.annotation.Nullable;
public final class Transformation {
private final Matrix4f matrix;
private boolean decomposed;
@Nullable
private Vector3f translation;
@Nullable
private Quaternion leftRotation;
@Nullable
private Vector3f scale;
@Nullable
private Quaternion rightRotation;
private static final Transformation IDENTITY;
public Transformation(@Nullable final Matrix4f b) {
if (b == null) {
this.matrix = Transformation.IDENTITY.matrix;
}
else {
this.matrix = b;
}
}
2020-07-22 06:32:50 +01:00
public Transformation(@Nullable final Vector3f g1, @Nullable final Quaternion d2, @Nullable final Vector3f g3, @Nullable final Quaternion d4) {
this.matrix = compose(g1, d2, g3, d4);
this.translation = ((g1 != null) ? g1 : new Vector3f());
this.leftRotation = ((d2 != null) ? d2 : Quaternion.ONE.copy());
this.scale = ((g3 != null) ? g3 : new Vector3f(1.0f, 1.0f, 1.0f));
this.rightRotation = ((d4 != null) ? d4 : Quaternion.ONE.copy());
2020-07-22 06:25:47 +01:00
this.decomposed = true;
}
public static Transformation identity() {
return Transformation.IDENTITY;
}
2020-07-22 06:32:50 +01:00
public Transformation compose(final Transformation f) {
2020-07-22 06:25:47 +01:00
final Matrix4f b3 = this.getMatrix();
2020-07-22 06:32:50 +01:00
b3.multiply(f.getMatrix());
2020-07-22 06:25:47 +01:00
return new Transformation(b3);
}
@Nullable
public Transformation inverse() {
if (this == Transformation.IDENTITY) {
return this;
}
final Matrix4f b2 = this.getMatrix();
if (b2.invert()) {
return new Transformation(b2);
}
return null;
}
private void ensureDecomposed() {
if (!this.decomposed) {
final Pair<Matrix3f, Vector3f> pair2 = toAffine(this.matrix);
final Triple<Quaternion, Vector3f, Quaternion> triple3 = ((Matrix3f)pair2.getFirst()).svdDecompose();
this.translation = (Vector3f)pair2.getSecond();
this.leftRotation = (Quaternion)triple3.getLeft();
this.scale = (Vector3f)triple3.getMiddle();
this.rightRotation = (Quaternion)triple3.getRight();
this.decomposed = true;
}
}
2020-07-22 06:32:50 +01:00
private static Matrix4f compose(@Nullable final Vector3f g1, @Nullable final Quaternion d2, @Nullable final Vector3f g3, @Nullable final Quaternion d4) {
2020-07-22 06:25:47 +01:00
final Matrix4f b5 = new Matrix4f();
b5.setIdentity();
2020-07-22 06:32:50 +01:00
if (d2 != null) {
b5.multiply(new Matrix4f(d2));
2020-07-22 06:25:47 +01:00
}
2020-07-22 06:32:50 +01:00
if (g3 != null) {
b5.multiply(Matrix4f.createScaleMatrix(g3.x(), g3.y(), g3.z()));
2020-07-22 06:25:47 +01:00
}
2020-07-22 06:32:50 +01:00
if (d4 != null) {
b5.multiply(new Matrix4f(d4));
2020-07-22 06:25:47 +01:00
}
2020-07-22 06:32:50 +01:00
if (g1 != null) {
b5.m03 = g1.x();
b5.m13 = g1.y();
b5.m23 = g1.z();
2020-07-22 06:25:47 +01:00
}
return b5;
}
public static Pair<Matrix3f, Vector3f> toAffine(final Matrix4f b) {
b.multiply(1.0f / b.m33);
2020-07-22 06:32:50 +01:00
final Vector3f g2 = new Vector3f(b.m03, b.m13, b.m23);
2020-07-22 06:25:47 +01:00
final Matrix3f a3 = new Matrix3f(b);
2020-07-22 06:32:50 +01:00
return (Pair<Matrix3f, Vector3f>)Pair.of(a3, g2);
2020-07-22 06:25:47 +01:00
}
public Matrix4f getMatrix() {
return this.matrix.copy();
}
public Quaternion getLeftRotation() {
this.ensureDecomposed();
return this.leftRotation.copy();
}
@Override
public boolean equals(final Object object) {
if (this == object) {
return true;
}
if (object == null || this.getClass() != object.getClass()) {
return false;
}
2020-07-22 06:32:50 +01:00
final Transformation f3 = (Transformation)object;
return Objects.equals(this.matrix, f3.matrix);
2020-07-22 06:25:47 +01:00
}
@Override
public int hashCode() {
return Objects.hash(this.matrix);
}
static {
final Matrix4f b1;
2020-07-22 06:32:50 +01:00
final Transformation f2;
2020-07-22 06:25:47 +01:00
IDENTITY = Util.<Transformation>make(() -> {
b1 = new Matrix4f();
b1.setIdentity();
2020-07-22 06:32:50 +01:00
f2 = new Transformation(b1);
f2.getLeftRotation();
return f2;
2020-07-22 06:25:47 +01:00
});
}
}