MultiPartModel.java

net.minecraft.client.renderer.block.dispatch.multipart.MultiPartModel

信息

  • 全限定名:net.minecraft.client.renderer.block.dispatch.multipart.MultiPartModel
  • 类型:public class
  • 包:net.minecraft.client.renderer.block.dispatch.multipart
  • 源码路径:src/main/java/net/minecraft/client/renderer/block/dispatch/multipart/MultiPartModel.java
  • 起始行号:L26
  • 实现:BlockStateModel
  • 职责:

    TODO

字段/常量

  • shared

    • 类型: MultiPartModel.SharedBakedState
    • 修饰符: private final
    • 源码定位: L27
    • 说明:

      TODO

  • blockState

    • 类型: BlockState
    • 修饰符: private final
    • 源码定位: L28
    • 说明:

      TODO

  • models

    • 类型: List<BlockStateModel>
    • 修饰符: private
    • 源码定位: L29
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.renderer.block.dispatch.multipart.MultiPartModel.Selector

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

      TODO

  • net.minecraft.client.renderer.block.dispatch.multipart.MultiPartModel.SharedBakedState

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

      TODO

  • net.minecraft.client.renderer.block.dispatch.multipart.MultiPartModel.Unbaked

    • 类型: class
    • 修饰符: public static
    • 源码定位: L126
    • 说明:

      TODO

  • net.minecraft.client.renderer.block.dispatch.multipart.MultiPartModel.Unbaked.Key

    • 类型: record
    • 修饰符: package-private
    • 源码定位: L161
    • 说明:

      TODO

构造器

private MultiPartModel(MultiPartModel.SharedBakedState shared, BlockState blockState) @ L31

  • 构造器名:MultiPartModel
  • 源码定位:L31
  • 修饰符:private

参数:

  • shared: MultiPartModel.SharedBakedState
  • blockState: BlockState

说明:

TODO

方法

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

public Material.Baked particleMaterial() @ L36

  • 方法名:particleMaterial
  • 源码定位:L36
  • 返回类型:Material.Baked
  • 修饰符:public

参数:

说明:

TODO

public int materialFlags() @ L41

  • 方法名:materialFlags
  • 源码定位:L41
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public void collectParts(RandomSource random, List<BlockStateModelPart> output) @ L47

  • 方法名:collectParts
  • 源码定位:L47
  • 返回类型:void
  • 修饰符:public

参数:

  • random: RandomSource
  • output: List

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class MultiPartModel implements BlockStateModel {
    private final MultiPartModel.SharedBakedState shared;
    private final BlockState blockState;
    private @Nullable List<BlockStateModel> models;
 
    private MultiPartModel(MultiPartModel.SharedBakedState shared, BlockState blockState) {
        this.shared = shared;
        this.blockState = blockState;
    }
 
    @Override
    public Material.Baked particleMaterial() {
        return this.shared.particleMaterial;
    }
 
    @BakedQuad.MaterialFlags
    @Override
    public int materialFlags() {
        return this.shared.materialFlags;
    }
 
    @Override
    public void collectParts(RandomSource random, List<BlockStateModelPart> output) {
        if (this.models == null) {
            this.models = this.shared.selectModels(this.blockState);
        }
 
        long seed = random.nextLong();
 
        for (BlockStateModel model : this.models) {
            random.setSeed(seed);
            model.collectParts(random, output);
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public record Selector<T>(Predicate<BlockState> condition, T model) {
        public <S> MultiPartModel.Selector<S> with(S newModel) {
            return new MultiPartModel.Selector<>(this.condition, newModel);
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    private static final class SharedBakedState {
        private final List<MultiPartModel.Selector<BlockStateModel>> selectors;
        private final Material.Baked particleMaterial;
        @BakedQuad.MaterialFlags
        private final int materialFlags;
        private final Map<BitSet, List<BlockStateModel>> subsets = new ConcurrentHashMap<>();
 
        private static BlockStateModel getFirstModel(List<MultiPartModel.Selector<BlockStateModel>> selectors) {
            if (selectors.isEmpty()) {
                throw new IllegalArgumentException("Model must have at least one selector");
            } else {
                return selectors.getFirst().model();
            }
        }
 
        @BakedQuad.MaterialFlags
        private static int computeMaterialFlags(List<MultiPartModel.Selector<BlockStateModel>> selectors) {
            int flags = 0;
 
            for (MultiPartModel.Selector<BlockStateModel> selector : selectors) {
                flags |= selector.model.materialFlags();
            }
 
            return flags;
        }
 
        public SharedBakedState(List<MultiPartModel.Selector<BlockStateModel>> selectors) {
            this.selectors = selectors;
            BlockStateModel firstModel = getFirstModel(selectors);
            this.particleMaterial = firstModel.particleMaterial();
            this.materialFlags = computeMaterialFlags(selectors);
        }
 
        public List<BlockStateModel> selectModels(BlockState state) {
            BitSet selectedModels = new BitSet();
 
            for (int i = 0; i < this.selectors.size(); i++) {
                if (this.selectors.get(i).condition.test(state)) {
                    selectedModels.set(i);
                }
            }
 
            return this.subsets.computeIfAbsent(selectedModels, selected -> {
                Builder<BlockStateModel> result = ImmutableList.builder();
 
                for (int ix = 0; ix < this.selectors.size(); ix++) {
                    if (selected.get(ix)) {
                        result.add((BlockStateModel)this.selectors.get(ix).model);
                    }
                }
 
                return result.build();
            });
        }
    }
 
    @OnlyIn(Dist.CLIENT)
    public static class Unbaked implements BlockStateModel.UnbakedRoot {
        private final List<MultiPartModel.Selector<BlockStateModel.Unbaked>> selectors;
        private final ModelBaker.SharedOperationKey<MultiPartModel.SharedBakedState> sharedStateKey = new ModelBaker.SharedOperationKey<MultiPartModel.SharedBakedState>(
            
        ) {
            {
                Objects.requireNonNull(Unbaked.this);
            }
 
            public MultiPartModel.SharedBakedState compute(ModelBaker modelBakery) {
                Builder<MultiPartModel.Selector<BlockStateModel>> selectors = ImmutableList.builderWithExpectedSize(Unbaked.this.selectors.size());
 
                for (MultiPartModel.Selector<BlockStateModel.Unbaked> selector : Unbaked.this.selectors) {
                    selectors.add(selector.with(selector.model.bake(modelBakery)));
                }
 
                return new MultiPartModel.SharedBakedState(selectors.build());
            }
        };
 
        public Unbaked(List<MultiPartModel.Selector<BlockStateModel.Unbaked>> selectors) {
            this.selectors = selectors;
        }
 
        @Override
        public Object visualEqualityGroup(BlockState blockState) {
            IntList triggeredSelectors = new IntArrayList();
 
            for (int i = 0; i < this.selectors.size(); i++) {
                if (this.selectors.get(i).condition.test(blockState)) {
                    triggeredSelectors.add(i);
                }
            }
 
            @OnlyIn(Dist.CLIENT)
            record Key(MultiPartModel.Unbaked model, IntList selectors) {
            }
 
            return new Key(this, triggeredSelectors);
        }
 
        @Override
        public void resolveDependencies(ResolvableModel.Resolver resolver) {
            this.selectors.forEach(s -> s.model.resolveDependencies(resolver));
        }
 
        @Override
        public BlockStateModel bake(BlockState blockState, ModelBaker modelBakery) {
            MultiPartModel.SharedBakedState shared = modelBakery.compute(this.sharedStateKey);
            return new MultiPartModel(shared, blockState);
        }
    }
}

引用的其他类