Слой текстуры предмета от NBT

Версия Minecraft
1.18.1
API
Forge
455
52
148
Какими способами можно предметам НЕ из своего мода добавить второй слой в зависимости от нбт булев-тега? С моделями и рендером на новых версиях максимально незнаком. В инете читал про Baked модели, но не особо понял что да как мне нужно. Может кто поподробнее рассказать? Или привести пример каких нибудь модов где это реализовано. Пожалуйста, не тинкерс констракт, закопаюсь в слоях абстракции..
 
Последнее редактирование:
Решение
Самое простое - увеличить все квады по оси Z на маленькое, но достаточное значение и сдвинуть вполовину этого по той же оси.
Проще всего это сделать при помощи Endothermic:
Java:
List<BakedQuad> quads = ...;
List<BakedQuad> fixedQuads = quads.stream()
    .map(LazyUnpackedQuad::apply)
    .map(q->q.scale(1, 1, 1.0015))
    .map(q->q.translate(0, 0, -0.0015/2))
    .map(LazyUnpackedQuad::toBakedQuad)
    .collect(toList());
455
52
148
Тема актуальна. За 2 недели более-менее разобрался, набросал вроде как оптимизированный код (раз клиент не умирает в агонии от прогрузки моделей - думаю норм)
Только осталась одна большая проблема, с которой я никак не могу разобраться. Брал реализацию наложенного слоя из мода SaltyMod, и столкнулся с такой проблемой отображения второго слоя: знает кто-нибудь как решить? может через Transformation что-то сделать? квады самого предмета добавлял, беря напрямую BakedModel::getQuads у дефолтной модели из ModelBakeEvent
Java:
  @SubscribeEvent
  public static void modelBakeEvent(ModelBakeEvent event) {
    for (Item item : ATMIntegrations.VALID_ITEMS) {
      ModelResourceLocation itemLocation = ForgeModelBakery.getInventoryVariant(ForgeRegistries.ITEMS.getKey(item).toString());
      BakedModel existingModel = event.getModelRegistry().get(itemLocation);
      if (existingModel != null) {
        /**здеся**/ATMItemModel model = new ATMItemModel(existingModel);
        event.getModelRegistry().put(itemLocation, model);
      } else {
        ATMIntegrations.LOGGER.error(itemLocation + " model is missing!");
      }
    }
  }
Java:
 public ATMItemModel(BakedModel model) {
    this.parentModel = model;
    /**здеся**/addQuads(model.getQuads(null, null, null));
  }

  public void addQuads(List<BakedQuad> collection) {
    ImmutableList.Builder builder = ImmutableList.builder();
    builder.addAll(quads);
    builder.addAll(collection);
    quads = builder.build();
  }
квады с этой текстурой добавляю в модель тут:
Java:
public class ATMItemOverrides extends ItemOverrides {
  public static final Int2ObjectMap<BakedModel> MODELS_CACHE = new Int2ObjectOpenHashMap<>();
  public static final Minecraft mc = Minecraft.getInstance();

  @Override
  public BakedModel resolve(BakedModel originalBakedModel, ItemStack stack, ClientLevel level, LivingEntity entity, int p_173469_) {
    int hash = calcHash(stack);
    if (!MODELS_CACHE.containsKey(hash)) {
      ATMItemModel newModel = new ATMItemModel(originalBakedModel);
      if (ATMTagContainer.isAmethyst(stack))
        /**здеся**/newModel.addQuads(ItemLayerModel.getQuadsForSprite(1, mc.getTextureAtlas(TextureAtlas.LOCATION_BLOCKS).apply(ATMModClientEvents.SPRITES_MAP.get("sword")), Transformation.identity()));
      return MODELS_CACHE.put(hash, newModel);
    }
    return MODELS_CACHE.getOrDefault(hash, originalBakedModel);
  }

  public static int calcHash(ItemStack stack) {
    return (stack.getItem().getRegistryName().toString() + ATMTagContainer.isAmethyst(stack)).hashCode();
  }
}
 
Последнее редактирование:
455
52
148
Это потом отладить всё можно. На трёхмерные модели я не планирую свою модель вешать, насчёт другого разрешения - не знаю, увидим. позже можем скрины скину)
 
7,003
315
1,470
Проблема в мерцании?
 
455
52
148
Да. В нём. Голову ломаю долго, нет идей как исправить. еще строить квады из базовой текстуры пробовал, ситуация не сильно меняется, всё равно есть мерцание на верхней грани модели
 
7,003
315
1,470
Самое простое - увеличить все квады по оси Z на маленькое, но достаточное значение и сдвинуть вполовину этого по той же оси.
Проще всего это сделать при помощи Endothermic:
Java:
List<BakedQuad> quads = ...;
List<BakedQuad> fixedQuads = quads.stream()
    .map(LazyUnpackedQuad::apply)
    .map(q->q.scale(1, 1, 1.0015))
    .map(q->q.translate(0, 0, -0.0015/2))
    .map(LazyUnpackedQuad::toBakedQuad)
    .collect(toList());
 
455
52
148
Спасибо, попробую как буду за компом. Только у меня еще мысля появилась сделать это не через прямой сдвиг квадов, а через Transformation последним аргументом в ItemLayerModel::getQuadsForSprite
 
455
52
148
Большое спасибо @hohserg! Работает без всяких проблем.
Java:
float delta = 0.0015f;
Transformation transformation = TransformationHelper.toTransformation(new ItemTransformation(new Vector3f(), new Vector3f(-delta / 2, -delta / 2, -delta / 2), new Vector3f(1 + delta, 1 + delta, 1 + delta)));
 
455
52
148
UP! @hohserg, не знаешь случаем, как можно исправить проблему, что модель до первого отображения не успевает сбилдиться и отображается отсутствующей текстурой? Вообще не представляю, как это исправить можно. Насколько помню, такая проблема появилась после внедрении мемоизации в код.
Java:
  @Override
  @SuppressWarnings("deprecation")
  public BakedModel resolve(BakedModel originalBakedModel, ItemStack stack, ClientLevel level, LivingEntity entity, int p_173469_) {
    BakedModel overrideModel = overrides.resolve(originalBakedModel, stack, level, entity, p_173469_);
    if (originalBakedModel != overrideModel)
      return overrideModel;
    int hash = calcHash(stack);
    if (!MODELS_CACHE.containsKey(hash)) {
      ATMItemModel newBakedModel = new ATMItemModel(originalBakedModel);
      if (ATMTagContainer.isAmethyst(stack)) {
        float delta = 0.0015f;
        newBakedModel.addQuads(ItemLayerModel.getQuadsForSprite(1, atlas.apply(resolveSprite(stack.getItem())), TransformationHelper.toTransformation(new ItemTransform(new Vector3f(), new Vector3f(-delta / 2, -delta / 2, -delta / 2), new Vector3f(1 + delta, 1 + delta, 1 + delta)))));
      }
      return MODELS_CACHE.put(hash, newBakedModel);
    }
    return MODELS_CACHE.getOrDefault(hash, originalBakedModel);
  }
}
 
Сверху