ItemModelGenerator.java
net.minecraft.client.resources.model.cuboid.ItemModelGenerator
信息
- 全限定名:net.minecraft.client.resources.model.cuboid.ItemModelGenerator
- 类型:public class
- 包:net.minecraft.client.resources.model.cuboid
- 源码路径:src/main/java/net/minecraft/client/resources/model/cuboid/ItemModelGenerator.java
- 起始行号:L26
- 实现:UnbakedModel
- 职责:
TODO
字段/常量
-
GENERATED_ITEM_MODEL_ID- 类型:
Identifier - 修饰符:
public static final - 源码定位:
L27 - 说明:
TODO
- 类型:
-
LAYERS- 类型:
List<String> - 修饰符:
public static final - 源码定位:
L28 - 说明:
TODO
- 类型:
-
MIN_Z- 类型:
float - 修饰符:
private static final - 源码定位:
L29 - 说明:
TODO
- 类型:
-
MAX_Z- 类型:
float - 修饰符:
private static final - 源码定位:
L30 - 说明:
TODO
- 类型:
-
TEXTURE_SLOTS- 类型:
TextureSlots.Data - 修饰符:
private static final - 源码定位:
L31 - 说明:
TODO
- 类型:
-
SOUTH_FACE_UVS- 类型:
CuboidFace.UVs - 修饰符:
private static final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
NORTH_FACE_UVS- 类型:
CuboidFace.UVs - 修饰符:
private static final - 源码定位:
L33 - 说明:
TODO
- 类型:
-
UV_SHRINK- 类型:
float - 修饰符:
private static final - 源码定位:
L34 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.resources.model.cuboid.ItemModelGenerator.ItemLayerKey- 类型:
record - 修饰符:
private - 源码定位:
L210 - 说明:
TODO
- 类型:
-
net.minecraft.client.resources.model.cuboid.ItemModelGenerator.SideDirection- 类型:
enum - 修饰符:
private static - 源码定位:
L221 - 说明:
TODO
- 类型:
-
net.minecraft.client.resources.model.cuboid.ItemModelGenerator.SideFace- 类型:
record - 修饰符:
private - 源码定位:
L243 - 说明:
TODO
- 类型:
构造器
- 无
方法
下面的方法块按源码顺序生成。
public TextureSlots.Data textureSlots() @ L36
- 方法名:textureSlots
- 源码定位:L36
- 返回类型:TextureSlots.Data
- 修饰符:public
参数:
- 无
说明:
TODO
public UnbakedGeometry geometry() @ L41
- 方法名:geometry
- 源码定位:L41
- 返回类型:UnbakedGeometry
- 修饰符:public
参数:
- 无
说明:
TODO
public UnbakedModel.GuiLight guiLight() @ L46
- 方法名:guiLight
- 源码定位:L46
- 返回类型:UnbakedModel.GuiLight
- 修饰符:public
参数:
- 无
说明:
TODO
private static QuadCollection bake(TextureSlots textureSlots, ModelBaker modelBaker, ModelState modelState, ModelDebugName name) @ L51
- 方法名:bake
- 源码定位:L51
- 返回类型:QuadCollection
- 修饰符:private static
参数:
- textureSlots: TextureSlots
- modelBaker: ModelBaker
- modelState: ModelState
- name: ModelDebugName
说明:
TODO
private static void bakeExtrudedSprite(QuadCollection.Builder builder, ModelBaker.Interner interner, ModelState modelState, BakedQuad.MaterialInfo materialInfo) @ L83
- 方法名:bakeExtrudedSprite
- 源码定位:L83
- 返回类型:void
- 修饰符:private static
参数:
- builder: QuadCollection.Builder
- interner: ModelBaker.Interner
- modelState: ModelState
- materialInfo: BakedQuad.MaterialInfo
说明:
TODO
private static void bakeSideFaces(QuadCollection.Builder builder, ModelBaker.Interner interner, ModelState modelState, BakedQuad.MaterialInfo materialInfo) @ L93
- 方法名:bakeSideFaces
- 源码定位:L93
- 返回类型:void
- 修饰符:private static
参数:
- builder: QuadCollection.Builder
- interner: ModelBaker.Interner
- modelState: ModelState
- materialInfo: BakedQuad.MaterialInfo
说明:
TODO
private static Collection<ItemModelGenerator.SideFace> getSideFaces(SpriteContents sprite) @ L170
- 方法名:getSideFaces
- 源码定位:L170
- 返回类型:Collection<ItemModelGenerator.SideFace>
- 修饰符:private static
参数:
- sprite: SpriteContents
说明:
TODO
private static void checkTransition(ItemModelGenerator.SideDirection facing, Set<ItemModelGenerator.SideFace> sideFaces, SpriteContents sprite, int frame, int x, int y, int width, int height) @ L190
- 方法名:checkTransition
- 源码定位:L190
- 返回类型:void
- 修饰符:private static
参数:
- facing: ItemModelGenerator.SideDirection
- sideFaces: Set<ItemModelGenerator.SideFace>
- sprite: SpriteContents
- frame: int
- x: int
- y: int
- width: int
- height: int
说明:
TODO
private static boolean isTransparent(SpriteContents sprite, int frame, int x, int y, int width, int height) @ L205
- 方法名:isTransparent
- 源码定位:L205
- 返回类型:boolean
- 修饰符:private static
参数:
- sprite: SpriteContents
- frame: int
- x: int
- y: int
- width: int
- height: int
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class ItemModelGenerator implements UnbakedModel {
public static final Identifier GENERATED_ITEM_MODEL_ID = Identifier.withDefaultNamespace("builtin/generated");
public static final List<String> LAYERS = List.of("layer0", "layer1", "layer2", "layer3", "layer4");
private static final float MIN_Z = 7.5F;
private static final float MAX_Z = 8.5F;
private static final TextureSlots.Data TEXTURE_SLOTS = new TextureSlots.Data.Builder().addReference("particle", "layer0").build();
private static final CuboidFace.UVs SOUTH_FACE_UVS = new CuboidFace.UVs(0.0F, 0.0F, 16.0F, 16.0F);
private static final CuboidFace.UVs NORTH_FACE_UVS = new CuboidFace.UVs(16.0F, 0.0F, 0.0F, 16.0F);
private static final float UV_SHRINK = 0.1F;
@Override
public TextureSlots.Data textureSlots() {
return TEXTURE_SLOTS;
}
@Override
public UnbakedGeometry geometry() {
return ItemModelGenerator::bake;
}
@Override
public UnbakedModel.@Nullable GuiLight guiLight() {
return UnbakedModel.GuiLight.FRONT;
}
private static QuadCollection bake(TextureSlots textureSlots, ModelBaker modelBaker, ModelState modelState, ModelDebugName name) {
QuadCollection singleResult = null;
QuadCollection.Builder builder = null;
for (int layerIndex = 0; layerIndex < LAYERS.size(); layerIndex++) {
String textureReference = LAYERS.get(layerIndex);
Material material = textureSlots.getMaterial(textureReference);
if (material == null) {
break;
}
Material.Baked bakedMaterial = modelBaker.materials().get(material, name);
QuadCollection bakedLayer = modelBaker.compute(new ItemModelGenerator.ItemLayerKey(bakedMaterial, modelState, layerIndex));
if (builder != null) {
builder.addAll(bakedLayer);
} else if (singleResult != null) {
builder = new QuadCollection.Builder();
builder.addAll(singleResult);
builder.addAll(bakedLayer);
singleResult = null;
} else {
singleResult = bakedLayer;
}
}
if (builder != null) {
return builder.build();
} else {
return singleResult != null ? singleResult : QuadCollection.EMPTY;
}
}
private static void bakeExtrudedSprite(
QuadCollection.Builder builder, ModelBaker.Interner interner, ModelState modelState, BakedQuad.MaterialInfo materialInfo
) {
Vector3f from = new Vector3f(0.0F, 0.0F, 7.5F);
Vector3f to = new Vector3f(16.0F, 16.0F, 8.5F);
builder.addUnculledFace(FaceBakery.bakeQuad(interner, from, to, SOUTH_FACE_UVS, Quadrant.R0, materialInfo, Direction.SOUTH, modelState, null));
builder.addUnculledFace(FaceBakery.bakeQuad(interner, from, to, NORTH_FACE_UVS, Quadrant.R0, materialInfo, Direction.NORTH, modelState, null));
bakeSideFaces(builder, interner, modelState, materialInfo);
}
private static void bakeSideFaces(QuadCollection.Builder builder, ModelBaker.Interner interner, ModelState modelState, BakedQuad.MaterialInfo materialInfo) {
SpriteContents sprite = materialInfo.sprite().contents();
float xScale = 16.0F / sprite.width();
float yScale = 16.0F / sprite.height();
Vector3f from = new Vector3f();
Vector3f to = new Vector3f();
for (ItemModelGenerator.SideFace sideFace : getSideFaces(sprite)) {
float x = sideFace.x();
float y = sideFace.y();
ItemModelGenerator.SideDirection sideDirection = sideFace.facing();
float u0 = x + 0.1F;
float u1 = x + 1.0F - 0.1F;
float v0;
float v1;
if (sideDirection.isHorizontal()) {
v0 = y + 0.1F;
v1 = y + 1.0F - 0.1F;
} else {
v0 = y + 1.0F - 0.1F;
v1 = y + 0.1F;
}
float startX = x;
float startY = y;
float endX = x;
float endY = y;
switch (sideDirection) {
case UP:
endX = x + 1.0F;
break;
case DOWN:
endX = x + 1.0F;
startY = y + 1.0F;
endY = y + 1.0F;
break;
case LEFT:
endY = y + 1.0F;
break;
case RIGHT:
startX = x + 1.0F;
endX = x + 1.0F;
endY = y + 1.0F;
}
startX *= xScale;
endX *= xScale;
startY *= yScale;
endY *= yScale;
startY = 16.0F - startY;
endY = 16.0F - endY;
switch (sideDirection) {
case UP:
from.set(startX, startY, 7.5F);
to.set(endX, startY, 8.5F);
break;
case DOWN:
from.set(startX, endY, 7.5F);
to.set(endX, endY, 8.5F);
break;
case LEFT:
from.set(startX, startY, 7.5F);
to.set(startX, endY, 8.5F);
break;
case RIGHT:
from.set(endX, startY, 7.5F);
to.set(endX, endY, 8.5F);
break;
default:
throw new UnsupportedOperationException();
}
CuboidFace.UVs uvs = new CuboidFace.UVs(u0 * xScale, v0 * yScale, u1 * xScale, v1 * yScale);
builder.addUnculledFace(FaceBakery.bakeQuad(interner, from, to, uvs, Quadrant.R0, materialInfo, sideDirection.getDirection(), modelState, null));
}
}
private static Collection<ItemModelGenerator.SideFace> getSideFaces(SpriteContents sprite) {
int width = sprite.width();
int height = sprite.height();
Set<ItemModelGenerator.SideFace> sideFaces = new HashSet<>();
sprite.getUniqueFrames().forEach(frame -> {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
boolean thisOpaque = !isTransparent(sprite, frame, x, y, width, height);
if (thisOpaque) {
checkTransition(ItemModelGenerator.SideDirection.UP, sideFaces, sprite, frame, x, y, width, height);
checkTransition(ItemModelGenerator.SideDirection.DOWN, sideFaces, sprite, frame, x, y, width, height);
checkTransition(ItemModelGenerator.SideDirection.LEFT, sideFaces, sprite, frame, x, y, width, height);
checkTransition(ItemModelGenerator.SideDirection.RIGHT, sideFaces, sprite, frame, x, y, width, height);
}
}
}
});
return sideFaces;
}
private static void checkTransition(
ItemModelGenerator.SideDirection facing,
Set<ItemModelGenerator.SideFace> sideFaces,
SpriteContents sprite,
int frame,
int x,
int y,
int width,
int height
) {
if (isTransparent(sprite, frame, x - facing.direction.getStepX(), y - facing.direction.getStepY(), width, height)) {
sideFaces.add(new ItemModelGenerator.SideFace(facing, x, y));
}
}
private static boolean isTransparent(SpriteContents sprite, int frame, int x, int y, int width, int height) {
return x >= 0 && y >= 0 && x < width && y < height ? sprite.isTransparent(frame, x, y) : true;
}
@OnlyIn(Dist.CLIENT)
private record ItemLayerKey(Material.Baked material, ModelState modelState, int layerIndex) implements ModelBaker.SharedOperationKey<QuadCollection> {
public QuadCollection compute(ModelBaker modelBakery) {
QuadCollection.Builder builder = new QuadCollection.Builder();
BakedQuad.MaterialInfo materialInfo = modelBakery.interner()
.materialInfo(BakedQuad.MaterialInfo.of(this.material, this.material.sprite().transparency(), this.layerIndex, true, 0));
ItemModelGenerator.bakeExtrudedSprite(builder, modelBakery.interner(), this.modelState, materialInfo);
return builder.build();
}
}
@OnlyIn(Dist.CLIENT)
private static enum SideDirection {
UP(Direction.UP),
DOWN(Direction.DOWN),
LEFT(Direction.EAST),
RIGHT(Direction.WEST);
private final Direction direction;
private SideDirection(Direction direction) {
this.direction = direction;
}
public Direction getDirection() {
return this.direction;
}
private boolean isHorizontal() {
return this == DOWN || this == UP;
}
}
@OnlyIn(Dist.CLIENT)
private record SideFace(ItemModelGenerator.SideDirection facing, int x, int y) {
}
}引用的其他类
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
实现/返回值
- 引用位置:
-
- 引用位置:
字段/方法调用/构造调用 - 关联成员:
CuboidFace.UVs(), UVs()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
FaceBakery.bakeQuad()
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
BakedQuad.MaterialInfo.of()
- 引用位置:
-
- 引用位置:
参数/方法调用/构造调用/返回值 - 关联成员:
Builder(), QuadCollection.Builder()
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数/字段/方法调用/构造调用/返回值 - 关联成员:
Builder(), TextureSlots.Data.Builder()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Identifier.withDefaultNamespace()
- 引用位置: