167 lines
4 KiB
Java
167 lines
4 KiB
Java
package com.mojang.blaze3d.vertex;
|
|
|
|
import com.mojang.math.MatrixUtil;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.NoSuchElementException;
|
|
import net.fabricmc.api.EnvType;
|
|
import net.fabricmc.api.Environment;
|
|
import net.minecraft.world.phys.Vec3;
|
|
import org.joml.Matrix3f;
|
|
import org.joml.Matrix4f;
|
|
import org.joml.Matrix4fc;
|
|
import org.joml.Quaternionfc;
|
|
import org.joml.Vector3f;
|
|
import org.joml.Vector3fc;
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public class PoseStack {
|
|
private final List<PoseStack.Pose> poses = new ArrayList(16);
|
|
private int lastIndex;
|
|
|
|
public PoseStack() {
|
|
this.poses.add(new PoseStack.Pose());
|
|
}
|
|
|
|
public void translate(double x, double y, double z) {
|
|
this.translate((float)x, (float)y, (float)z);
|
|
}
|
|
|
|
public void translate(float x, float y, float z) {
|
|
this.last().translate(x, y, z);
|
|
}
|
|
|
|
public void translate(Vec3 vector) {
|
|
this.translate(vector.x, vector.y, vector.z);
|
|
}
|
|
|
|
public void scale(float x, float y, float z) {
|
|
this.last().scale(x, y, z);
|
|
}
|
|
|
|
public void mulPose(Quaternionfc pose) {
|
|
this.last().rotate(pose);
|
|
}
|
|
|
|
public void rotateAround(Quaternionfc quaternion, float x, float y, float z) {
|
|
this.last().rotateAround(quaternion, x, y, z);
|
|
}
|
|
|
|
public void pushPose() {
|
|
PoseStack.Pose pose = this.last();
|
|
this.lastIndex++;
|
|
if (this.lastIndex >= this.poses.size()) {
|
|
this.poses.add(pose.copy());
|
|
} else {
|
|
((PoseStack.Pose)this.poses.get(this.lastIndex)).set(pose);
|
|
}
|
|
}
|
|
|
|
public void popPose() {
|
|
if (this.lastIndex == 0) {
|
|
throw new NoSuchElementException();
|
|
} else {
|
|
this.lastIndex--;
|
|
}
|
|
}
|
|
|
|
public PoseStack.Pose last() {
|
|
return (PoseStack.Pose)this.poses.get(this.lastIndex);
|
|
}
|
|
|
|
public boolean isEmpty() {
|
|
return this.lastIndex == 0;
|
|
}
|
|
|
|
public void setIdentity() {
|
|
this.last().setIdentity();
|
|
}
|
|
|
|
public void mulPose(Matrix4fc pose) {
|
|
this.last().mulPose(pose);
|
|
}
|
|
|
|
@Environment(EnvType.CLIENT)
|
|
public static final class Pose {
|
|
private final Matrix4f pose = new Matrix4f();
|
|
private final Matrix3f normal = new Matrix3f();
|
|
private boolean trustedNormals = true;
|
|
|
|
private void computeNormalMatrix() {
|
|
this.normal.set(this.pose).invert().transpose();
|
|
this.trustedNormals = false;
|
|
}
|
|
|
|
void set(PoseStack.Pose pose) {
|
|
this.pose.set(pose.pose);
|
|
this.normal.set(pose.normal);
|
|
this.trustedNormals = pose.trustedNormals;
|
|
}
|
|
|
|
public Matrix4f pose() {
|
|
return this.pose;
|
|
}
|
|
|
|
public Matrix3f normal() {
|
|
return this.normal;
|
|
}
|
|
|
|
public Vector3f transformNormal(Vector3fc pos, Vector3f destination) {
|
|
return this.transformNormal(pos.x(), pos.y(), pos.z(), destination);
|
|
}
|
|
|
|
public Vector3f transformNormal(float x, float y, float z, Vector3f destination) {
|
|
Vector3f vector3f = this.normal.transform(x, y, z, destination);
|
|
return this.trustedNormals ? vector3f : vector3f.normalize();
|
|
}
|
|
|
|
public Matrix4f translate(float x, float y, float z) {
|
|
return this.pose.translate(x, y, z);
|
|
}
|
|
|
|
public void scale(float x, float y, float z) {
|
|
this.pose.scale(x, y, z);
|
|
if (Math.abs(x) == Math.abs(y) && Math.abs(y) == Math.abs(z)) {
|
|
if (x < 0.0F || y < 0.0F || z < 0.0F) {
|
|
this.normal.scale(Math.signum(x), Math.signum(y), Math.signum(z));
|
|
}
|
|
} else {
|
|
this.normal.scale(1.0F / x, 1.0F / y, 1.0F / z);
|
|
this.trustedNormals = false;
|
|
}
|
|
}
|
|
|
|
public void rotate(Quaternionfc pose) {
|
|
this.pose.rotate(pose);
|
|
this.normal.rotate(pose);
|
|
}
|
|
|
|
public void rotateAround(Quaternionfc pose, float x, float y, float z) {
|
|
this.pose.rotateAround(pose, x, y, z);
|
|
this.normal.rotate(pose);
|
|
}
|
|
|
|
public void setIdentity() {
|
|
this.pose.identity();
|
|
this.normal.identity();
|
|
this.trustedNormals = true;
|
|
}
|
|
|
|
public void mulPose(Matrix4fc pose) {
|
|
this.pose.mul(pose);
|
|
if (!MatrixUtil.isPureTranslation(pose)) {
|
|
if (MatrixUtil.isOrthonormal(pose)) {
|
|
this.normal.mul(new Matrix3f(pose));
|
|
} else {
|
|
this.computeNormalMatrix();
|
|
}
|
|
}
|
|
}
|
|
|
|
public PoseStack.Pose copy() {
|
|
PoseStack.Pose pose = new PoseStack.Pose();
|
|
pose.set(this);
|
|
return pose;
|
|
}
|
|
}
|
|
}
|