RangeSelectItemModel.java

net.minecraft.client.renderer.item.RangeSelectItemModel

信息

  • 全限定名:net.minecraft.client.renderer.item.RangeSelectItemModel
  • 类型:public class
  • 包:net.minecraft.client.renderer.item
  • 源码路径:src/main/java/net/minecraft/client/renderer/item/RangeSelectItemModel.java
  • 起始行号:L25
  • 实现:ItemModel
  • 职责:

    TODO

字段/常量

  • LINEAR_SEARCH_THRESHOLD

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

      TODO

  • property

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

      TODO

  • scale

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

      TODO

  • thresholds

    • 类型: float[]
    • 修饰符: private final
    • 源码定位: L29
    • 说明:

      TODO

  • models

    • 类型: ItemModel[]
    • 修饰符: private final
    • 源码定位: L30
    • 说明:

      TODO

  • fallback

    • 类型: ItemModel
    • 修饰符: private final
    • 源码定位: L31
    • 说明:

      TODO

内部类/嵌套类型

  • net.minecraft.client.renderer.item.RangeSelectItemModel.Entry

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

      TODO

  • net.minecraft.client.renderer.item.RangeSelectItemModel.Unbaked

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

      TODO

构造器

private RangeSelectItemModel(RangeSelectItemModelProperty property, float scale, float[] thresholds, ItemModel[] models, ItemModel fallback) @ L33

  • 构造器名:RangeSelectItemModel
  • 源码定位:L33
  • 修饰符:private

参数:

  • property: RangeSelectItemModelProperty
  • scale: float
  • thresholds: float[]
  • models: ItemModel[]
  • fallback: ItemModel

说明:

TODO

方法

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

private static int lastIndexLessOrEqual(float[] haystack, float needle) @ L41

  • 方法名:lastIndexLessOrEqual
  • 源码定位:L41
  • 返回类型:int
  • 修饰符:private static

参数:

  • haystack: float[]
  • needle: float

说明:

TODO

public void update(ItemStackRenderState output, ItemStack item, ItemModelResolver resolver, ItemDisplayContext displayContext, ClientLevel level, ItemOwner owner, int seed) @ L61

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

参数:

  • output: ItemStackRenderState
  • item: ItemStack
  • resolver: ItemModelResolver
  • displayContext: ItemDisplayContext
  • level: ClientLevel
  • owner: ItemOwner
  • seed: int

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class RangeSelectItemModel implements ItemModel {
    private static final int LINEAR_SEARCH_THRESHOLD = 16;
    private final RangeSelectItemModelProperty property;
    private final float scale;
    private final float[] thresholds;
    private final ItemModel[] models;
    private final ItemModel fallback;
 
    private RangeSelectItemModel(RangeSelectItemModelProperty property, float scale, float[] thresholds, ItemModel[] models, ItemModel fallback) {
        this.property = property;
        this.thresholds = thresholds;
        this.models = models;
        this.fallback = fallback;
        this.scale = scale;
    }
 
    private static int lastIndexLessOrEqual(float[] haystack, float needle) {
        if (haystack.length < 16) {
            for (int i = 0; i < haystack.length; i++) {
                if (haystack[i] > needle) {
                    return i - 1;
                }
            }
 
            return haystack.length - 1;
        } else {
            int index = Arrays.binarySearch(haystack, needle);
            if (index < 0) {
                int insertionPoint = ~index;
                return insertionPoint - 1;
            } else {
                return index;
            }
        }
    }
 
    @Override
    public void update(
        ItemStackRenderState output,
        ItemStack item,
        ItemModelResolver resolver,
        ItemDisplayContext displayContext,
        @Nullable ClientLevel level,
        @Nullable ItemOwner owner,
        int seed
    ) {
        output.appendModelIdentityElement(this);
        float value = this.property.get(item, level, owner, seed) * this.scale;
        ItemModel selectedModel;
        if (Float.isNaN(value)) {
            selectedModel = this.fallback;
        } else {
            int index = lastIndexLessOrEqual(this.thresholds, value);
            selectedModel = index == -1 ? this.fallback : this.models[index];
        }
 
        selectedModel.update(output, item, resolver, displayContext, level, owner, seed);
    }
 
    @OnlyIn(Dist.CLIENT)
    public record Entry(float threshold, ItemModel.Unbaked model) {
        public static final Codec<RangeSelectItemModel.Entry> CODEC = RecordCodecBuilder.create(
            i -> i.group(
                    Codec.FLOAT.fieldOf("threshold").forGetter(RangeSelectItemModel.Entry::threshold),
                    ItemModels.CODEC.fieldOf("model").forGetter(RangeSelectItemModel.Entry::model)
                )
                .apply(i, RangeSelectItemModel.Entry::new)
        );
        public static final Comparator<RangeSelectItemModel.Entry> BY_THRESHOLD = Comparator.comparingDouble(RangeSelectItemModel.Entry::threshold);
    }
 
    @OnlyIn(Dist.CLIENT)
    public record Unbaked(
        Optional<Transformation> transformation,
        RangeSelectItemModelProperty property,
        float scale,
        List<RangeSelectItemModel.Entry> entries,
        Optional<ItemModel.Unbaked> fallback
    ) implements ItemModel.Unbaked {
        public static final MapCodec<RangeSelectItemModel.Unbaked> MAP_CODEC = RecordCodecBuilder.mapCodec(
            i -> i.group(
                    Transformation.EXTENDED_CODEC.optionalFieldOf("transformation").forGetter(RangeSelectItemModel.Unbaked::transformation),
                    RangeSelectItemModelProperties.MAP_CODEC.forGetter(RangeSelectItemModel.Unbaked::property),
                    Codec.FLOAT.optionalFieldOf("scale", 1.0F).forGetter(RangeSelectItemModel.Unbaked::scale),
                    RangeSelectItemModel.Entry.CODEC.listOf().fieldOf("entries").forGetter(RangeSelectItemModel.Unbaked::entries),
                    ItemModels.CODEC.optionalFieldOf("fallback").forGetter(RangeSelectItemModel.Unbaked::fallback)
                )
                .apply(i, RangeSelectItemModel.Unbaked::new)
        );
 
        @Override
        public MapCodec<RangeSelectItemModel.Unbaked> type() {
            return MAP_CODEC;
        }
 
        @Override
        public ItemModel bake(ItemModel.BakingContext context, Matrix4fc transformation) {
            Matrix4fc childTransform = Transformation.compose(transformation, this.transformation);
            float[] thresholds = new float[this.entries.size()];
            ItemModel[] models = new ItemModel[this.entries.size()];
            List<RangeSelectItemModel.Entry> mutableEntries = new ArrayList<>(this.entries);
            mutableEntries.sort(RangeSelectItemModel.Entry.BY_THRESHOLD);
 
            for (int i = 0; i < mutableEntries.size(); i++) {
                RangeSelectItemModel.Entry entry = mutableEntries.get(i);
                thresholds[i] = entry.threshold;
                models[i] = entry.model.bake(context, childTransform);
            }
 
            ItemModel bakedFallback = this.fallback
                .<ItemModel>map(m -> m.bake(context, childTransform))
                .orElseGet(() -> context.missingItemModel(childTransform));
            return new RangeSelectItemModel(this.property, this.scale, thresholds, models, bakedFallback);
        }
 
        @Override
        public void resolveDependencies(ResolvableModel.Resolver resolver) {
            this.fallback.ifPresent(m -> m.resolveDependencies(resolver));
            this.entries.forEach(entry -> entry.model.resolveDependencies(resolver));
        }
    }
}

引用的其他类