ModelBakery.java

net.minecraft.client.resources.model.ModelBakery

信息

  • 全限定名:net.minecraft.client.resources.model.ModelBakery
  • 类型:public class
  • 包:net.minecraft.client.resources.model
  • 源码路径:src/main/java/net/minecraft/client/resources/model/ModelBakery.java
  • 起始行号:L50
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L51
    • 说明:

      TODO

  • FIRE_0

    • 类型: SpriteId
    • 修饰符: public static final
    • 源码定位: L52
    • 说明:

      TODO

  • FIRE_1

    • 类型: SpriteId
    • 修饰符: public static final
    • 源码定位: L53
    • 说明:

      TODO

  • DESTROY_STAGE_COUNT

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L54
    • 说明:

      TODO

  • DESTROY_STAGES

    • 类型: List<Identifier>
    • 修饰符: public static final
    • 源码定位: L55
    • 说明:

      TODO

  • BREAKING_LOCATIONS

    • 类型: List<Identifier>
    • 修饰符: public static final
    • 源码定位: L58
    • 说明:

      TODO

  • DESTROY_TYPES

    • 类型: List<RenderType>
    • 修饰符: public static final
    • 源码定位: L61
    • 说明:

      TODO

  • IDENTITY

    • 类型: Matrix4fc
    • 修饰符: private static final
    • 源码定位: L62
    • 说明:

      TODO

  • entityModelSet

    • 类型: EntityModelSet
    • 修饰符: private final
    • 源码定位: L63
    • 说明:

      TODO

  • sprites

    • 类型: SpriteGetter
    • 修饰符: private final
    • 源码定位: L64
    • 说明:

      TODO

  • playerSkinRenderCache

    • 类型: PlayerSkinRenderCache
    • 修饰符: private final
    • 源码定位: L65
    • 说明:

      TODO

  • unbakedBlockStateModels

    • 类型: Map<BlockState,BlockStateModel.UnbakedRoot>
    • 修饰符: private final
    • 源码定位: L66
    • 说明:

      TODO

  • clientInfos

    • 类型: Map<Identifier,ClientItem>
    • 修饰符: private final
    • 源码定位: L67
    • 说明:

      TODO

  • resolvedModels

    • 类型: Map<Identifier,ResolvedModel>
    • 修饰符: private final
    • 源码定位: L68
    • 说明:

      TODO

  • missingModel

    • 类型: ResolvedModel
    • 修饰符: private final
    • 源码定位: L69
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.resources.model.ModelBakery.BakingResult

    • 类型: record
    • 修饰符: public
    • 源码定位: L140
    • 说明:

      TODO

  • net.minecraft.client.resources.model.ModelBakery.InternerImpl

    • 类型: class
    • 修饰符: private static
    • 源码定位: L152
    • 说明:

      TODO

  • net.minecraft.client.resources.model.ModelBakery.MissingModels

    • 类型: record
    • 修饰符: public
    • 源码定位: L168
    • 说明:

      TODO

  • net.minecraft.client.resources.model.ModelBakery.ModelBakerImpl

    • 类型: class
    • 修饰符: private
    • 源码定位: L211
    • 说明:

      TODO

构造器

public ModelBakery(EntityModelSet entityModelSet, SpriteGetter sprites, PlayerSkinRenderCache playerSkinRenderCache, Map<BlockState,BlockStateModel.UnbakedRoot> unbakedBlockStateModels, Map<Identifier,ClientItem> clientInfos, Map<Identifier,ResolvedModel> resolvedModels, ResolvedModel missingModel) @ L71

  • 构造器名:ModelBakery
  • 源码定位:L71
  • 修饰符:public

参数:

  • entityModelSet: EntityModelSet
  • sprites: SpriteGetter
  • playerSkinRenderCache: PlayerSkinRenderCache
  • unbakedBlockStateModels: Map<BlockState,BlockStateModel.UnbakedRoot>
  • clientInfos: Map<Identifier,ClientItem>
  • resolvedModels: Map<Identifier,ResolvedModel>
  • missingModel: ResolvedModel

说明:

TODO

方法

下面的方法块按源码顺序生成。

public CompletableFuture<ModelBakery.BakingResult> bakeModels(MaterialBaker materials, Executor taskExecutor) @ L89

  • 方法名:bakeModels
  • 源码定位:L89
  • 返回类型:CompletableFuture<ModelBakery.BakingResult>
  • 修饰符:public

参数:

  • materials: MaterialBaker
  • taskExecutor: Executor

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class ModelBakery {
    private static final Logger LOGGER = LogUtils.getLogger();
    public static final SpriteId FIRE_0 = Sheets.BLOCKS_MAPPER.defaultNamespaceApply("fire_0");
    public static final SpriteId FIRE_1 = Sheets.BLOCKS_MAPPER.defaultNamespaceApply("fire_1");
    public static final int DESTROY_STAGE_COUNT = 10;
    public static final List<Identifier> DESTROY_STAGES = IntStream.range(0, 10)
        .mapToObj(i -> Identifier.withDefaultNamespace("block/destroy_stage_" + i))
        .collect(Collectors.toList());
    public static final List<Identifier> BREAKING_LOCATIONS = DESTROY_STAGES.stream()
        .map(location -> location.withPath(path -> "textures/" + path + ".png"))
        .collect(Collectors.toList());
    public static final List<RenderType> DESTROY_TYPES = BREAKING_LOCATIONS.stream().map(RenderTypes::crumbling).collect(Collectors.toList());
    private static final Matrix4fc IDENTITY = new Matrix4f();
    private final EntityModelSet entityModelSet;
    private final SpriteGetter sprites;
    private final PlayerSkinRenderCache playerSkinRenderCache;
    private final Map<BlockState, BlockStateModel.UnbakedRoot> unbakedBlockStateModels;
    private final Map<Identifier, ClientItem> clientInfos;
    private final Map<Identifier, ResolvedModel> resolvedModels;
    private final ResolvedModel missingModel;
 
    public ModelBakery(
        EntityModelSet entityModelSet,
        SpriteGetter sprites,
        PlayerSkinRenderCache playerSkinRenderCache,
        Map<BlockState, BlockStateModel.UnbakedRoot> unbakedBlockStateModels,
        Map<Identifier, ClientItem> clientInfos,
        Map<Identifier, ResolvedModel> resolvedModels,
        ResolvedModel missingModel
    ) {
        this.entityModelSet = entityModelSet;
        this.sprites = sprites;
        this.playerSkinRenderCache = playerSkinRenderCache;
        this.unbakedBlockStateModels = unbakedBlockStateModels;
        this.clientInfos = clientInfos;
        this.resolvedModels = resolvedModels;
        this.missingModel = missingModel;
    }
 
    public CompletableFuture<ModelBakery.BakingResult> bakeModels(MaterialBaker materials, Executor taskExecutor) {
        ModelBakery.InternerImpl interner = new ModelBakery.InternerImpl();
        ModelBakery.MissingModels missingModels = ModelBakery.MissingModels.bake(this.missingModel, materials, interner);
        ModelBakery.ModelBakerImpl baker = new ModelBakery.ModelBakerImpl(materials, interner, missingModels);
        CompletableFuture<Map<BlockState, BlockStateModel>> bakedBlockStateModelFuture = ParallelMapTransform.schedule(
            this.unbakedBlockStateModels, (blockState, model) -> {
                try {
                    return model.bake(blockState, baker);
                } catch (Exception var4x) {
                    LOGGER.warn("Unable to bake model: '{}': {}", blockState, var4x);
                    return null;
                }
            }, taskExecutor
        );
        CompletableFuture<Map<Identifier, ItemModel>> bakedItemStackModelFuture = ParallelMapTransform.schedule(
            this.clientInfos,
            (location, clientInfo) -> {
                try {
                    return clientInfo.model()
                        .bake(
                            new ItemModel.BakingContext(
                                baker, this.entityModelSet, this.sprites, this.playerSkinRenderCache, missingModels.item, clientInfo.registrySwapper()
                            ),
                            IDENTITY
                        );
                } catch (Exception var6x) {
                    LOGGER.warn("Unable to bake item model: '{}'", location, var6x);
                    return null;
                }
            },
            taskExecutor
        );
        Map<Identifier, ClientItem.Properties> itemStackModelProperties = new HashMap<>(this.clientInfos.size());
        this.clientInfos.forEach((id, clientInfo) -> {
            ClientItem.Properties properties = clientInfo.properties();
            if (!properties.equals(ClientItem.Properties.DEFAULT)) {
                itemStackModelProperties.put(id, properties);
            }
        });
        return bakedBlockStateModelFuture.thenCombine(
            bakedItemStackModelFuture,
            (bakedBlockStateModels, bakedItemStateModels) -> new ModelBakery.BakingResult(
                missingModels,
                (Map<BlockState, BlockStateModel>)bakedBlockStateModels,
                (Map<Identifier, ItemModel>)bakedItemStateModels,
                itemStackModelProperties
            )
        );
    }
 
    @OnlyIn(Dist.CLIENT)
    public record BakingResult(
        ModelBakery.MissingModels missingModels,
        Map<BlockState, BlockStateModel> blockStateModels,
        Map<Identifier, ItemModel> itemStackModels,
        Map<Identifier, ClientItem.Properties> itemProperties
    ) {
        public BlockStateModel getBlockStateModel(BlockState blockState) {
            return this.blockStateModels.getOrDefault(blockState, this.missingModels.block);
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private static class InternerImpl implements ModelBaker.Interner {
        private final Interner<Vector3fc> vectors = Interners.newStrongInterner();
        private final Interner<BakedQuad.MaterialInfo> materialInfos = Interners.newStrongInterner();
 
        @Override
        public Vector3fc vector(Vector3fc v) {
            return this.vectors.intern(v);
        }
 
        @Override
        public BakedQuad.MaterialInfo materialInfo(BakedQuad.MaterialInfo material) {
            return this.materialInfos.intern(material);
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public record MissingModels(BlockStateModelPart blockPart, BlockStateModel block, MissingItemModel item, FluidModel fluid) {
        public static ModelBakery.MissingModels bake(ResolvedModel unbaked, MaterialBaker materials, ModelBaker.Interner interner) {
            ModelBaker missingModelBakery = new ModelBaker() {
                @Override
                public ResolvedModel getModel(Identifier location) {
                    throw new IllegalStateException("Missing model can't have dependencies, but asked for " + location);
                }
 
                @Override
                public BlockStateModelPart missingBlockModelPart() {
                    throw new IllegalStateException();
                }
 
                @Override
                public <T> T compute(ModelBaker.SharedOperationKey<T> key) {
                    return key.compute(this);
                }
 
                @Override
                public MaterialBaker materials() {
                    return materials;
                }
 
                @Override
                public ModelBaker.Interner interner() {
                    return interner;
                }
            };
            TextureSlots textureSlots = unbaked.getTopTextureSlots();
            boolean hasAmbientOcclusion = unbaked.getTopAmbientOcclusion();
            boolean usesBlockLight = unbaked.getTopGuiLight().lightLikeBlock();
            ItemTransforms transforms = unbaked.getTopTransforms();
            QuadCollection geometry = unbaked.bakeTopGeometry(textureSlots, missingModelBakery, BlockModelRotation.IDENTITY);
            Material.Baked particleMaterial = unbaked.resolveParticleMaterial(textureSlots, missingModelBakery);
            SimpleModelWrapper missingModelPart = new SimpleModelWrapper(geometry, hasAmbientOcclusion, particleMaterial);
            BlockStateModel bakedBlockModel = new SingleVariant(missingModelPart);
            MissingItemModel bakedItemModel = new MissingItemModel(geometry.getAll(), new ModelRenderProperties(usesBlockLight, particleMaterial, transforms));
            FluidModel bakedFluidModel = new FluidModel(ChunkSectionLayer.SOLID, particleMaterial, particleMaterial, null, null);
            return new ModelBakery.MissingModels(missingModelPart, bakedBlockModel, bakedItemModel, bakedFluidModel);
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private class ModelBakerImpl implements ModelBaker {
        private final MaterialBaker materials;
        private final ModelBaker.Interner interner;
        private final ModelBakery.MissingModels missingModels;
        private final Map<ModelBaker.SharedOperationKey<Object>, Object> operationCache;
        private final Function<ModelBaker.SharedOperationKey<Object>, Object> cacheComputeFunction;
 
        private ModelBakerImpl(MaterialBaker materials, ModelBaker.Interner interner, ModelBakery.MissingModels missingModels) {
            Objects.requireNonNull(ModelBakery.this);
            super();
            this.operationCache = new ConcurrentHashMap<>();
            this.cacheComputeFunction = k -> k.compute(this);
            this.materials = materials;
            this.interner = interner;
            this.missingModels = missingModels;
        }
 
        @Override
        public BlockStateModelPart missingBlockModelPart() {
            return this.missingModels.blockPart;
        }
 
        @Override
        public MaterialBaker materials() {
            return this.materials;
        }
 
        @Override
        public ModelBaker.Interner interner() {
            return this.interner;
        }
 
        @Override
        public ResolvedModel getModel(Identifier location) {
            ResolvedModel result = ModelBakery.this.resolvedModels.get(location);
            if (result == null) {
                ModelBakery.LOGGER.warn("Requested a model that was not discovered previously: {}", location);
                return ModelBakery.this.missingModel;
            } else {
                return result;
            }
        }
 
        @Override
        public <T> T compute(ModelBaker.SharedOperationKey<T> key) {
            return (T)this.operationCache.computeIfAbsent((ModelBaker.SharedOperationKey<Object>)key, this.cacheComputeFunction);
        }
    }
}

引用的其他类