FaceBakery.java
net.minecraft.client.resources.model.cuboid.FaceBakery
信息
- 全限定名:net.minecraft.client.resources.model.cuboid.FaceBakery
- 类型:public class
- 包:net.minecraft.client.resources.model.cuboid
- 源码路径:src/main/java/net/minecraft/client/resources/model/cuboid/FaceBakery.java
- 起始行号:L25
- 职责:
TODO
字段/常量
BLOCK_MIDDLE- 类型:
Vector3fc - 修饰符:
private static final - 源码定位:
L26 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
- 无
方法
下面的方法块按源码顺序生成。
static CuboidFace.UVs defaultFaceUV(Vector3fc from, Vector3fc to, Direction facing) @ L28
- 方法名:defaultFaceUV
- 源码定位:L28
- 返回类型:CuboidFace.UVs
- 修饰符:static
参数:
- from: Vector3fc
- to: Vector3fc
- facing: Direction
说明:
TODO
private static Transparency computeMaterialTransparency(Material.Baked material, CuboidFace.UVs uvs) @ L40
- 方法名:computeMaterialTransparency
- 源码定位:L40
- 返回类型:Transparency
- 修饰符:private static
参数:
- material: Material.Baked
- uvs: CuboidFace.UVs
说明:
TODO
public static BakedQuad bakeQuad(ModelBaker modelBaker, Vector3fc from, Vector3fc to, CuboidFace face, Material.Baked material, Direction facing, ModelState modelState, CuboidRotation elementRotation, boolean shade, int lightEmission) @ L53
- 方法名:bakeQuad
- 源码定位:L53
- 返回类型:BakedQuad
- 修饰符:public static
参数:
- modelBaker: ModelBaker
- from: Vector3fc
- to: Vector3fc
- face: CuboidFace
- material: Material.Baked
- facing: Direction
- modelState: ModelState
- elementRotation: CuboidRotation
- shade: boolean
- lightEmission: int
说明:
TODO
public static BakedQuad bakeQuad(ModelBaker.Interner interner, Vector3fc from, Vector3fc to, CuboidFace.UVs uvs, Quadrant uvRotation, BakedQuad.MaterialInfo materialInfo, Direction facing, ModelState modelState, CuboidRotation elementRotation) @ L76
- 方法名:bakeQuad
- 源码定位:L76
- 返回类型:BakedQuad
- 修饰符:public static
参数:
- interner: ModelBaker.Interner
- from: Vector3fc
- to: Vector3fc
- uvs: CuboidFace.UVs
- uvRotation: Quadrant
- materialInfo: BakedQuad.MaterialInfo
- facing: Direction
- modelState: ModelState
- elementRotation: CuboidRotation
说明:
TODO
private static void bakeVertex(int index, FaceInfo faceInfo, CuboidFace.UVs uvs, Quadrant uvRotation, Matrix4fc uvTransform, Vector3fc from, Vector3fc to, BakedQuad.MaterialInfo materialInfo, Transformation rotation, CuboidRotation elementRotation, Vector3fc[] positionOutput, long[] uvOutput, ModelBaker.Interner interner) @ L129
- 方法名:bakeVertex
- 源码定位:L129
- 返回类型:void
- 修饰符:private static
参数:
- index: int
- faceInfo: FaceInfo
- uvs: CuboidFace.UVs
- uvRotation: Quadrant
- uvTransform: Matrix4fc
- from: Vector3fc
- to: Vector3fc
- materialInfo: BakedQuad.MaterialInfo
- rotation: Transformation
- elementRotation: CuboidRotation
- positionOutput: Vector3fc[]
- uvOutput: long[]
- interner: ModelBaker.Interner
说明:
TODO
private static float cornerToCenter(float value) @ L171
- 方法名:cornerToCenter
- 源码定位:L171
- 返回类型:float
- 修饰符:private static
参数:
- value: float
说明:
TODO
private static float centerToCorner(float value) @ L175
- 方法名:centerToCorner
- 源码定位:L175
- 返回类型:float
- 修饰符:private static
参数:
- value: float
说明:
TODO
private static void rotateVertexBy(Vector3f vertex, Vector3fc origin, Matrix4fc transformation) @ L179
- 方法名:rotateVertexBy
- 源码定位:L179
- 返回类型:void
- 修饰符:private static
参数:
- vertex: Vector3f
- origin: Vector3fc
- transformation: Matrix4fc
说明:
TODO
private static Direction calculateFacing(Vector3fc[] positions) @ L185
- 方法名:calculateFacing
- 源码定位:L185
- 返回类型:Direction
- 修饰符:private static
参数:
- positions: Vector3fc[]
说明:
TODO
private static Direction findClosestDirection(Vector3f direction) @ L191
- 方法名:findClosestDirection
- 源码定位:L191
- 返回类型:Direction
- 修饰符:private static
参数:
- direction: Vector3f
说明:
TODO
private static void recalculateWinding(Vector3fc[] positions, long[] uvs, Direction direction) @ L210
- 方法名:recalculateWinding
- 源码定位:L210
- 返回类型:void
- 修饰符:private static
参数:
- positions: Vector3fc[]
- uvs: long[]
- direction: Direction
说明:
TODO
private static int findVertex(Vector3fc[] positions, int start, float x, float y, float z) @ L267
- 方法名:findVertex
- 源码定位:L267
- 返回类型:int
- 修饰符:private static
参数:
- positions: Vector3fc[]
- start: int
- x: float
- y: float
- z: float
说明:
TODO
private static void swap(Vector3fc[] array, int indexA, int indexB) @ L278
- 方法名:swap
- 源码定位:L278
- 返回类型:void
- 修饰符:private static
参数:
- array: Vector3fc[]
- indexA: int
- indexB: int
说明:
TODO
private static void swap(long[] array, int indexA, int indexB) @ L284
- 方法名:swap
- 源码定位:L284
- 返回类型:void
- 修饰符:private static
参数:
- array: long[]
- indexA: int
- indexB: int
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class FaceBakery {
private static final Vector3fc BLOCK_MIDDLE = new Vector3f(0.5F, 0.5F, 0.5F);
@VisibleForTesting
static CuboidFace.UVs defaultFaceUV(Vector3fc from, Vector3fc to, Direction facing) {
return switch (facing) {
case DOWN -> new CuboidFace.UVs(from.x(), 16.0F - to.z(), to.x(), 16.0F - from.z());
case UP -> new CuboidFace.UVs(from.x(), from.z(), to.x(), to.z());
case NORTH -> new CuboidFace.UVs(16.0F - to.x(), 16.0F - to.y(), 16.0F - from.x(), 16.0F - from.y());
case SOUTH -> new CuboidFace.UVs(from.x(), 16.0F - to.y(), to.x(), 16.0F - from.y());
case WEST -> new CuboidFace.UVs(from.z(), 16.0F - to.y(), to.z(), 16.0F - from.y());
case EAST -> new CuboidFace.UVs(16.0F - to.z(), 16.0F - to.y(), 16.0F - from.z(), 16.0F - from.y());
};
}
private static Transparency computeMaterialTransparency(Material.Baked material, CuboidFace.UVs uvs) {
return material.forceTranslucent()
? Transparency.TRANSLUCENT
: material.sprite()
.contents()
.computeTransparency(
Math.min(uvs.minU(), uvs.maxU()) / 16.0F,
Math.min(uvs.minV(), uvs.maxV()) / 16.0F,
Math.max(uvs.minU(), uvs.maxU()) / 16.0F,
Math.max(uvs.minV(), uvs.maxV()) / 16.0F
);
}
public static BakedQuad bakeQuad(
ModelBaker modelBaker,
Vector3fc from,
Vector3fc to,
CuboidFace face,
Material.Baked material,
Direction facing,
ModelState modelState,
@Nullable CuboidRotation elementRotation,
boolean shade,
int lightEmission
) {
CuboidFace.UVs uvs = face.uvs();
if (uvs == null) {
uvs = defaultFaceUV(from, to, facing);
}
Transparency transparency = computeMaterialTransparency(material, uvs);
ModelBaker.Interner interner = modelBaker.interner();
BakedQuad.MaterialInfo materialInfo = interner.materialInfo(BakedQuad.MaterialInfo.of(material, transparency, face.tintIndex(), shade, lightEmission));
return bakeQuad(interner, from, to, uvs, face.rotation(), materialInfo, facing, modelState, elementRotation);
}
public static BakedQuad bakeQuad(
ModelBaker.Interner interner,
Vector3fc from,
Vector3fc to,
CuboidFace.UVs uvs,
Quadrant uvRotation,
BakedQuad.MaterialInfo materialInfo,
Direction facing,
ModelState modelState,
@Nullable CuboidRotation elementRotation
) {
Matrix4fc uvTransform = modelState.inverseFaceTransformation(facing);
Vector3fc[] vertexPositions = new Vector3fc[4];
long[] vertexPackedUvs = new long[4];
FaceInfo faceInfo = FaceInfo.fromFacing(facing);
for (int i = 0; i < 4; i++) {
bakeVertex(
i,
faceInfo,
uvs,
uvRotation,
uvTransform,
from,
to,
materialInfo,
modelState.transformation(),
elementRotation,
vertexPositions,
vertexPackedUvs,
interner
);
}
Direction finalDirection = calculateFacing(vertexPositions);
if (elementRotation == null && finalDirection != null) {
recalculateWinding(vertexPositions, vertexPackedUvs, finalDirection);
}
return new BakedQuad(
vertexPositions[0],
vertexPositions[1],
vertexPositions[2],
vertexPositions[3],
vertexPackedUvs[0],
vertexPackedUvs[1],
vertexPackedUvs[2],
vertexPackedUvs[3],
Objects.requireNonNullElse(finalDirection, Direction.UP),
materialInfo
);
}
private static void bakeVertex(
int index,
FaceInfo faceInfo,
CuboidFace.UVs uvs,
Quadrant uvRotation,
Matrix4fc uvTransform,
Vector3fc from,
Vector3fc to,
BakedQuad.MaterialInfo materialInfo,
Transformation rotation,
@Nullable CuboidRotation elementRotation,
Vector3fc[] positionOutput,
long[] uvOutput,
ModelBaker.Interner interner
) {
FaceInfo.VertexInfo vertexInfo = faceInfo.getVertexInfo(index);
Vector3f vertex = vertexInfo.select(from, to).div(16.0F);
if (elementRotation != null) {
rotateVertexBy(vertex, elementRotation.origin(), elementRotation.transform());
}
if (rotation != Transformation.IDENTITY) {
rotateVertexBy(vertex, BLOCK_MIDDLE, rotation.getMatrix());
}
float rawU = CuboidFace.getU(uvs, uvRotation, index);
float rawV = CuboidFace.getV(uvs, uvRotation, index);
float transformedV;
float transformedU;
if (MatrixUtil.isIdentity(uvTransform)) {
transformedU = rawU;
transformedV = rawV;
} else {
Vector3f transformedUV = uvTransform.transformPosition(new Vector3f(cornerToCenter(rawU), cornerToCenter(rawV), 0.0F));
transformedU = centerToCorner(transformedUV.x);
transformedV = centerToCorner(transformedUV.y);
}
positionOutput[index] = interner.vector(vertex);
uvOutput[index] = UVPair.pack(materialInfo.sprite().getU(transformedU), materialInfo.sprite().getV(transformedV));
}
private static float cornerToCenter(float value) {
return value - 0.5F;
}
private static float centerToCorner(float value) {
return value + 0.5F;
}
private static void rotateVertexBy(Vector3f vertex, Vector3fc origin, Matrix4fc transformation) {
vertex.sub(origin);
transformation.transformPosition(vertex);
vertex.add(origin);
}
private static @Nullable Direction calculateFacing(Vector3fc[] positions) {
Vector3f normal = new Vector3f();
GeometryUtils.normal(positions[0], positions[1], positions[2], normal);
return findClosestDirection(normal);
}
private static @Nullable Direction findClosestDirection(Vector3f direction) {
if (!direction.isFinite()) {
return null;
} else {
Direction best = null;
float closestProduct = 0.0F;
for (Direction candidate : Direction.values()) {
float product = direction.dot(candidate.getUnitVec3f());
if (product >= 0.0F && product > closestProduct) {
closestProduct = product;
best = candidate;
}
}
return best;
}
}
private static void recalculateWinding(Vector3fc[] positions, long[] uvs, Direction direction) {
float minX = 999.0F;
float minY = 999.0F;
float minZ = 999.0F;
float maxX = -999.0F;
float maxY = -999.0F;
float maxZ = -999.0F;
for (int i = 0; i < 4; i++) {
Vector3fc position = positions[i];
float x = position.x();
float y = position.y();
float z = position.z();
if (x < minX) {
minX = x;
}
if (y < minY) {
minY = y;
}
if (z < minZ) {
minZ = z;
}
if (x > maxX) {
maxX = x;
}
if (y > maxY) {
maxY = y;
}
if (z > maxZ) {
maxZ = z;
}
}
FaceInfo info = FaceInfo.fromFacing(direction);
for (int vertex = 0; vertex < 4; vertex++) {
FaceInfo.VertexInfo vertInfo = info.getVertexInfo(vertex);
float newX = vertInfo.xFace().select(minX, minY, minZ, maxX, maxY, maxZ);
float newY = vertInfo.yFace().select(minX, minY, minZ, maxX, maxY, maxZ);
float newZ = vertInfo.zFace().select(minX, minY, minZ, maxX, maxY, maxZ);
int vertexToSwap = findVertex(positions, vertex, newX, newY, newZ);
if (vertexToSwap == -1) {
throw new IllegalStateException("Can't find vertex to swap");
}
if (vertexToSwap != vertex) {
swap(positions, vertexToSwap, vertex);
swap(uvs, vertexToSwap, vertex);
}
}
}
private static int findVertex(Vector3fc[] positions, int start, float x, float y, float z) {
for (int i = start; i < 4; i++) {
Vector3fc position = positions[i];
if (x == position.x() && y == position.y() && z == position.z()) {
return i;
}
}
return -1;
}
private static void swap(Vector3fc[] array, int indexA, int indexB) {
Vector3fc tmp = array[indexA];
array[indexA] = array[indexB];
array[indexB] = tmp;
}
private static void swap(long[] array, int indexA, int indexB) {
long tmp = array[indexA];
array[indexA] = array[indexB];
array[indexB] = tmp;
}
}引用的其他类
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
MatrixUtil.isIdentity()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
UVPair.pack()
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
FaceInfo.fromFacing()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用/构造调用/返回值 - 关联成员:
CuboidFace.UVs(), CuboidFace.getU(), CuboidFace.getV(), UVs()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用/构造调用/返回值 - 关联成员:
BakedQuad(), BakedQuad.MaterialInfo.of()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用/返回值 - 关联成员:
Direction.values()
- 引用位置: