329 lines
14 KiB
Java
329 lines
14 KiB
Java
package net.minecraft.client.renderer.block.model;
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.mojang.math.MatrixUtil;
|
|
import com.mojang.math.Quadrant;
|
|
import com.mojang.math.Transformation;
|
|
import java.util.function.Consumer;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.client.renderer.FaceInfo;
|
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
import net.minecraft.client.resources.model.ModelState;
|
|
import net.minecraft.core.Direction;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraftforge.api.distmarker.Dist;
|
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
import org.joml.Matrix4f;
|
|
import org.joml.Matrix4fc;
|
|
import org.joml.Quaternionf;
|
|
import org.joml.Vector3f;
|
|
import org.joml.Vector3fc;
|
|
import org.joml.Vector4f;
|
|
|
|
@OnlyIn(Dist.CLIENT)
|
|
public class FaceBakery {
|
|
public static final int VERTEX_INT_SIZE = 8;
|
|
private static final float RESCALE_22_5 = 1.0F / (float)Math.cos((float) (Math.PI / 8)) - 1.0F;
|
|
private static final float RESCALE_45 = 1.0F / (float)Math.cos((float) (Math.PI / 4)) - 1.0F;
|
|
public static final int VERTEX_COUNT = 4;
|
|
private static final int COLOR_INDEX = 3;
|
|
public static final int UV_INDEX = 4;
|
|
|
|
@VisibleForTesting
|
|
static BlockElementFace.UVs defaultFaceUV(Vector3fc p_393926_, Vector3fc p_395023_, Direction p_393336_) {
|
|
return switch (p_393336_) {
|
|
case DOWN -> new BlockElementFace.UVs(p_393926_.x(), 16.0F - p_395023_.z(), p_395023_.x(), 16.0F - p_393926_.z());
|
|
case UP -> new BlockElementFace.UVs(p_393926_.x(), p_393926_.z(), p_395023_.x(), p_395023_.z());
|
|
case NORTH -> new BlockElementFace.UVs(16.0F - p_395023_.x(), 16.0F - p_395023_.y(), 16.0F - p_393926_.x(), 16.0F - p_393926_.y());
|
|
case SOUTH -> new BlockElementFace.UVs(p_393926_.x(), 16.0F - p_395023_.y(), p_395023_.x(), 16.0F - p_393926_.y());
|
|
case WEST -> new BlockElementFace.UVs(p_393926_.z(), 16.0F - p_395023_.y(), p_395023_.z(), 16.0F - p_393926_.y());
|
|
case EAST -> new BlockElementFace.UVs(16.0F - p_395023_.z(), 16.0F - p_395023_.y(), 16.0F - p_393926_.z(), 16.0F - p_393926_.y());
|
|
};
|
|
}
|
|
|
|
public static BakedQuad bakeQuad(
|
|
Vector3fc p_393181_,
|
|
Vector3fc p_395026_,
|
|
BlockElementFace p_111603_,
|
|
TextureAtlasSprite p_111604_,
|
|
Direction p_111605_,
|
|
ModelState p_111606_,
|
|
@Nullable BlockElementRotation p_111607_,
|
|
boolean p_111608_,
|
|
int p_364904_
|
|
) {
|
|
BlockElementFace.UVs blockelementface$uvs = p_111603_.uvs();
|
|
if (blockelementface$uvs == null) {
|
|
blockelementface$uvs = defaultFaceUV(p_393181_, p_395026_, p_111605_);
|
|
}
|
|
|
|
blockelementface$uvs = shrinkUVs(p_111604_, blockelementface$uvs);
|
|
Matrix4fc matrix4fc = p_111606_.inverseFaceTransformation(p_111605_);
|
|
int[] aint = makeVertices(
|
|
blockelementface$uvs, p_111603_.rotation(), matrix4fc, p_111604_, p_111605_, setupShape(p_393181_, p_395026_), p_111606_.transformation(), p_111607_
|
|
);
|
|
Direction direction = calculateFacing(aint);
|
|
if (p_111607_ == null) {
|
|
recalculateWinding(aint, direction);
|
|
}
|
|
|
|
return new BakedQuad(aint, p_111603_.tintIndex(), direction, p_111604_, p_111608_, p_364904_);
|
|
}
|
|
|
|
private static BlockElementFace.UVs shrinkUVs(TextureAtlasSprite p_397002_, BlockElementFace.UVs p_394057_) {
|
|
float f = p_394057_.minU();
|
|
float f1 = p_394057_.minV();
|
|
float f2 = p_394057_.maxU();
|
|
float f3 = p_394057_.maxV();
|
|
float f4 = p_397002_.uvShrinkRatio();
|
|
float f5 = (f + f + f2 + f2) / 4.0F;
|
|
float f6 = (f1 + f1 + f3 + f3) / 4.0F;
|
|
return new BlockElementFace.UVs(Mth.lerp(f4, f, f5), Mth.lerp(f4, f1, f6), Mth.lerp(f4, f2, f5), Mth.lerp(f4, f3, f6));
|
|
}
|
|
|
|
private static int[] makeVertices(
|
|
BlockElementFace.UVs p_391814_,
|
|
Quadrant p_393719_,
|
|
Matrix4fc p_397140_,
|
|
TextureAtlasSprite p_111575_,
|
|
Direction p_111576_,
|
|
float[] p_111577_,
|
|
Transformation p_111578_,
|
|
@Nullable BlockElementRotation p_111579_
|
|
) {
|
|
FaceInfo faceinfo = FaceInfo.fromFacing(p_111576_);
|
|
int[] aint = new int[32];
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
bakeVertex(aint, i, faceinfo, p_391814_, p_393719_, p_397140_, p_111577_, p_111575_, p_111578_, p_111579_);
|
|
}
|
|
|
|
return aint;
|
|
}
|
|
|
|
private static float[] setupShape(Vector3fc p_393902_, Vector3fc p_394068_) {
|
|
float[] afloat = new float[Direction.values().length];
|
|
afloat[FaceInfo.Constants.MIN_X] = p_393902_.x() / 16.0F;
|
|
afloat[FaceInfo.Constants.MIN_Y] = p_393902_.y() / 16.0F;
|
|
afloat[FaceInfo.Constants.MIN_Z] = p_393902_.z() / 16.0F;
|
|
afloat[FaceInfo.Constants.MAX_X] = p_394068_.x() / 16.0F;
|
|
afloat[FaceInfo.Constants.MAX_Y] = p_394068_.y() / 16.0F;
|
|
afloat[FaceInfo.Constants.MAX_Z] = p_394068_.z() / 16.0F;
|
|
return afloat;
|
|
}
|
|
|
|
private static void bakeVertex(
|
|
int[] p_111621_,
|
|
int p_111622_,
|
|
FaceInfo p_394082_,
|
|
BlockElementFace.UVs p_395065_,
|
|
Quadrant p_392208_,
|
|
Matrix4fc p_396750_,
|
|
float[] p_111625_,
|
|
TextureAtlasSprite p_111626_,
|
|
Transformation p_111627_,
|
|
@Nullable BlockElementRotation p_111628_
|
|
) {
|
|
FaceInfo.VertexInfo faceinfo$vertexinfo = p_394082_.getVertexInfo(p_111622_);
|
|
Vector3f vector3f = new Vector3f(
|
|
p_111625_[faceinfo$vertexinfo.xFace], p_111625_[faceinfo$vertexinfo.yFace], p_111625_[faceinfo$vertexinfo.zFace]
|
|
);
|
|
applyElementRotation(vector3f, p_111628_);
|
|
applyModelRotation(vector3f, p_111627_);
|
|
float f = BlockElementFace.getU(p_395065_, p_392208_, p_111622_);
|
|
float f1 = BlockElementFace.getV(p_395065_, p_392208_, p_111622_);
|
|
float f2;
|
|
float f3;
|
|
if (MatrixUtil.isIdentity(p_396750_)) {
|
|
f3 = f;
|
|
f2 = f1;
|
|
} else {
|
|
Vector3f vector3f1 = p_396750_.transformPosition(new Vector3f(cornerToCenter(f), cornerToCenter(f1), 0.0F));
|
|
f3 = centerToCorner(vector3f1.x);
|
|
f2 = centerToCorner(vector3f1.y);
|
|
}
|
|
|
|
fillVertex(p_111621_, p_111622_, vector3f, p_111626_, f3, f2);
|
|
}
|
|
|
|
private static float cornerToCenter(float p_393791_) {
|
|
return p_393791_ - 0.5F;
|
|
}
|
|
|
|
private static float centerToCorner(float p_392923_) {
|
|
return p_392923_ + 0.5F;
|
|
}
|
|
|
|
private static void fillVertex(int[] p_111615_, int p_111616_, Vector3f p_254291_, TextureAtlasSprite p_111618_, float p_393253_, float p_396335_) {
|
|
int i = p_111616_ * 8;
|
|
p_111615_[i] = Float.floatToRawIntBits(p_254291_.x());
|
|
p_111615_[i + 1] = Float.floatToRawIntBits(p_254291_.y());
|
|
p_111615_[i + 2] = Float.floatToRawIntBits(p_254291_.z());
|
|
p_111615_[i + 3] = -1;
|
|
p_111615_[i + 4] = Float.floatToRawIntBits(p_111618_.getU(p_393253_));
|
|
p_111615_[i + 4 + 1] = Float.floatToRawIntBits(p_111618_.getV(p_396335_));
|
|
}
|
|
|
|
private static void applyElementRotation(Vector3f p_254412_, @Nullable BlockElementRotation p_254150_) {
|
|
if (p_254150_ != null) {
|
|
Vector3f vector3f;
|
|
Vector3f vector3f1;
|
|
switch (p_254150_.axis()) {
|
|
case X:
|
|
vector3f = new Vector3f(1.0F, 0.0F, 0.0F);
|
|
vector3f1 = new Vector3f(0.0F, 1.0F, 1.0F);
|
|
break;
|
|
case Y:
|
|
vector3f = new Vector3f(0.0F, 1.0F, 0.0F);
|
|
vector3f1 = new Vector3f(1.0F, 0.0F, 1.0F);
|
|
break;
|
|
case Z:
|
|
vector3f = new Vector3f(0.0F, 0.0F, 1.0F);
|
|
vector3f1 = new Vector3f(1.0F, 1.0F, 0.0F);
|
|
break;
|
|
default:
|
|
throw new IllegalArgumentException("There are only 3 axes");
|
|
}
|
|
|
|
Quaternionf quaternionf = new Quaternionf().rotationAxis(p_254150_.angle() * (float) (Math.PI / 180.0), vector3f);
|
|
if (p_254150_.rescale()) {
|
|
if (Math.abs(p_254150_.angle()) == 22.5F) {
|
|
vector3f1.mul(RESCALE_22_5);
|
|
} else {
|
|
vector3f1.mul(RESCALE_45);
|
|
}
|
|
|
|
vector3f1.add(1.0F, 1.0F, 1.0F);
|
|
} else {
|
|
vector3f1.set(1.0F, 1.0F, 1.0F);
|
|
}
|
|
|
|
rotateVertexBy(p_254412_, new Vector3f(p_254150_.origin()), new Matrix4f().rotation(quaternionf), vector3f1);
|
|
}
|
|
}
|
|
|
|
private static void applyModelRotation(Vector3f p_254561_, Transformation p_253793_) {
|
|
if (p_253793_ != Transformation.identity()) {
|
|
rotateVertexBy(p_254561_, new Vector3f(0.5F, 0.5F, 0.5F), p_253793_.getMatrix(), new Vector3f(1.0F, 1.0F, 1.0F));
|
|
}
|
|
}
|
|
|
|
private static void rotateVertexBy(Vector3f p_393378_, Vector3fc p_396712_, Matrix4fc p_394901_, Vector3fc p_395897_) {
|
|
Vector4f vector4f = p_394901_.transform(new Vector4f(p_393378_.x() - p_396712_.x(), p_393378_.y() - p_396712_.y(), p_393378_.z() - p_396712_.z(), 1.0F));
|
|
vector4f.mul(new Vector4f(p_395897_, 1.0F));
|
|
p_393378_.set(vector4f.x() + p_396712_.x(), vector4f.y() + p_396712_.y(), vector4f.z() + p_396712_.z());
|
|
}
|
|
|
|
private static Direction calculateFacing(int[] p_111613_) {
|
|
Vector3f vector3f = vectorFromData(p_111613_, 0);
|
|
Vector3f vector3f1 = vectorFromData(p_111613_, 8);
|
|
Vector3f vector3f2 = vectorFromData(p_111613_, 16);
|
|
Vector3f vector3f3 = new Vector3f(vector3f).sub(vector3f1);
|
|
Vector3f vector3f4 = new Vector3f(vector3f2).sub(vector3f1);
|
|
Vector3f vector3f5 = new Vector3f(vector3f4).cross(vector3f3).normalize();
|
|
if (!vector3f5.isFinite()) {
|
|
return Direction.UP;
|
|
} else {
|
|
Direction direction = null;
|
|
float f = 0.0F;
|
|
|
|
for (Direction direction1 : Direction.values()) {
|
|
float f1 = vector3f5.dot(direction1.getUnitVec3f());
|
|
if (f1 >= 0.0F && f1 > f) {
|
|
f = f1;
|
|
direction = direction1;
|
|
}
|
|
}
|
|
|
|
return direction == null ? Direction.UP : direction;
|
|
}
|
|
}
|
|
|
|
private static float xFromData(int[] p_393171_, int p_394995_) {
|
|
return Float.intBitsToFloat(p_393171_[p_394995_]);
|
|
}
|
|
|
|
private static float yFromData(int[] p_396587_, int p_391994_) {
|
|
return Float.intBitsToFloat(p_396587_[p_391994_ + 1]);
|
|
}
|
|
|
|
private static float zFromData(int[] p_392671_, int p_392811_) {
|
|
return Float.intBitsToFloat(p_392671_[p_392811_ + 2]);
|
|
}
|
|
|
|
private static Vector3f vectorFromData(int[] p_391584_, int p_394245_) {
|
|
return new Vector3f(xFromData(p_391584_, p_394245_), yFromData(p_391584_, p_394245_), zFromData(p_391584_, p_394245_));
|
|
}
|
|
|
|
private static void recalculateWinding(int[] p_111631_, Direction p_111632_) {
|
|
int[] aint = new int[p_111631_.length];
|
|
System.arraycopy(p_111631_, 0, aint, 0, p_111631_.length);
|
|
float[] afloat = new float[Direction.values().length];
|
|
afloat[FaceInfo.Constants.MIN_X] = 999.0F;
|
|
afloat[FaceInfo.Constants.MIN_Y] = 999.0F;
|
|
afloat[FaceInfo.Constants.MIN_Z] = 999.0F;
|
|
afloat[FaceInfo.Constants.MAX_X] = -999.0F;
|
|
afloat[FaceInfo.Constants.MAX_Y] = -999.0F;
|
|
afloat[FaceInfo.Constants.MAX_Z] = -999.0F;
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
int j = 8 * i;
|
|
float f = xFromData(aint, j);
|
|
float f1 = yFromData(aint, j);
|
|
float f2 = zFromData(aint, j);
|
|
if (f < afloat[FaceInfo.Constants.MIN_X]) {
|
|
afloat[FaceInfo.Constants.MIN_X] = f;
|
|
}
|
|
|
|
if (f1 < afloat[FaceInfo.Constants.MIN_Y]) {
|
|
afloat[FaceInfo.Constants.MIN_Y] = f1;
|
|
}
|
|
|
|
if (f2 < afloat[FaceInfo.Constants.MIN_Z]) {
|
|
afloat[FaceInfo.Constants.MIN_Z] = f2;
|
|
}
|
|
|
|
if (f > afloat[FaceInfo.Constants.MAX_X]) {
|
|
afloat[FaceInfo.Constants.MAX_X] = f;
|
|
}
|
|
|
|
if (f1 > afloat[FaceInfo.Constants.MAX_Y]) {
|
|
afloat[FaceInfo.Constants.MAX_Y] = f1;
|
|
}
|
|
|
|
if (f2 > afloat[FaceInfo.Constants.MAX_Z]) {
|
|
afloat[FaceInfo.Constants.MAX_Z] = f2;
|
|
}
|
|
}
|
|
|
|
FaceInfo faceinfo = FaceInfo.fromFacing(p_111632_);
|
|
|
|
for (int i1 = 0; i1 < 4; i1++) {
|
|
int j1 = 8 * i1;
|
|
FaceInfo.VertexInfo faceinfo$vertexinfo = faceinfo.getVertexInfo(i1);
|
|
float f8 = afloat[faceinfo$vertexinfo.xFace];
|
|
float f3 = afloat[faceinfo$vertexinfo.yFace];
|
|
float f4 = afloat[faceinfo$vertexinfo.zFace];
|
|
p_111631_[j1] = Float.floatToRawIntBits(f8);
|
|
p_111631_[j1 + 1] = Float.floatToRawIntBits(f3);
|
|
p_111631_[j1 + 2] = Float.floatToRawIntBits(f4);
|
|
|
|
for (int k = 0; k < 4; k++) {
|
|
int l = 8 * k;
|
|
float f5 = xFromData(aint, l);
|
|
float f6 = yFromData(aint, l);
|
|
float f7 = zFromData(aint, l);
|
|
if (Mth.equal(f8, f5) && Mth.equal(f3, f6) && Mth.equal(f4, f7)) {
|
|
p_111631_[j1 + 4] = aint[l + 4];
|
|
p_111631_[j1 + 4 + 1] = aint[l + 4 + 1];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void extractPositions(int[] p_394217_, Consumer<Vector3f> p_393107_) {
|
|
for (int i = 0; i < 4; i++) {
|
|
p_393107_.accept(vectorFromData(p_394217_, 8 * i));
|
|
}
|
|
}
|
|
} |