feat: flower crown model type + layers baking (WIP)
Some checks failed
Build / build (push) Has been cancelled

This commit is contained in:
SushiCannibale 2025-08-06 00:30:44 +02:00
parent 9f0e679dd1
commit a8990da272
2 changed files with 155 additions and 0 deletions

View file

@ -0,0 +1,155 @@
package fr.sushi.charmsnfabrics.client.model;
import com.mojang.math.Transformation;
import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder;
import fr.sushi.charmsnfabrics.CharmsAndFabrics;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.BlockElement;
import net.minecraft.client.renderer.block.model.ItemTransforms;
import net.minecraft.client.renderer.block.model.TextureSlots;
import net.minecraft.client.renderer.item.*;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.*;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.client.ClientHooks;
import net.neoforged.neoforge.client.model.ComposedModelState;
import net.neoforged.neoforge.client.model.UnbakedElementsHelper;
import org.jetbrains.annotations.Nullable;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import java.util.ArrayList;
import java.util.List;
public class FlowerCrownItemModel implements ItemModel
{
private static final ModelDebugName DEBUG_NAME =
() -> "FlowerCrownItemModel";
// private final FlowerCrownItemModel.Unbaked unbakedModel;
// private final ItemTransforms transforms;
private final ItemModel bakedBase;
private final BakingContext bakingContext;
private final ItemTransforms baseTransform;
public FlowerCrownItemModel(ItemModel bakedBase, BakingContext context)
{
this.bakedBase = bakedBase;
this.bakingContext = context;
ResolvedModel baseItemModel = bakingContext.blockModelBaker().getModel(
ResourceLocation.withDefaultNamespace("item/generated"));
this.baseTransform = baseItemModel.getTopTransforms();
}
private ResourceLocation getFlowerLocation(int layer)
{
return ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID,
"flowers/flower" + layer);
}
/* Prevent Z fighting */
private Transformation getLayerTransform(int layer)
{
return new Transformation(new Vector3f(), new Quaternionf(),
new Vector3f(0.0f, 0.0f, 1.0f + (layer / 100f)),
new Quaternionf());
}
public ItemModel bakeForColors(List<DyeColor> colors)
{
ModelState state = BlockModelRotation.X0_Y0;
SpriteGetter sprites = this.bakingContext.blockModelBaker().sprites();
List<ItemModel> submodels = new ArrayList<>();
submodels.add(this.bakedBase);
for (int layer = 0; layer < colors.size(); layer++)
{
ResourceLocation texture = this.getFlowerLocation(layer);
Material material = ClientHooks.getBlockMaterial(texture);
TextureAtlasSprite sprite = sprites.get(material, DEBUG_NAME);
/* ***** TODO: Multiply pixels with dye color **** */
List<BlockElement> unbaked =
UnbakedElementsHelper.createUnbakedItemElements(0, sprite);
List<BakedQuad> quads =
UnbakedElementsHelper.bakeElements(unbaked, mat -> sprite,
new ComposedModelState(state,
this.getLayerTransform(layer)));
ModelRenderProperties renderProperties =
new ModelRenderProperties(false, sprite,
this.baseTransform);
submodels.add(
new BlockModelWrapper(List.of(), quads, renderProperties));
}
/* ****************************************************************** */
return new CompositeModel(submodels);
}
@Override
public void update(ItemStackRenderState renderState, ItemStack stack,
ItemModelResolver itemModelResolver,
ItemDisplayContext displayContext, @Nullable ClientLevel level,
@Nullable LivingEntity entity, int seed)
{
ItemStackRenderState.LayerRenderState freshLayer =
renderState.newLayer();
}
public record Unbaked(
ResourceLocation baseModel) implements ItemModel.Unbaked
{
public static final MapCodec<FlowerCrownItemModel.Unbaked> MAP_CODEC =
RecordCodecBuilder.mapCodec(unbaked -> unbaked
.group(ResourceLocation.CODEC.fieldOf("base").forGetter(
FlowerCrownItemModel.Unbaked::baseModel))
.apply(unbaked, FlowerCrownItemModel.Unbaked::new));
@Override
public MapCodec<? extends ItemModel.Unbaked> type()
{
return MAP_CODEC;
}
@Override
public ItemModel bake(BakingContext context)
{
ModelBaker modelbaker = context.blockModelBaker();
ResolvedModel resolved = modelbaker.getModel(this.baseModel);
List<BakedQuad> quads = resolved
.bakeTopGeometry(resolved.getTopTextureSlots(), modelbaker,
BlockModelRotation.X0_Y0).getAll();
ItemModel bakedBase = new BlockModelWrapper(List.of(), quads,
this.getRenderProperties(context));
return new FlowerCrownItemModel(bakedBase, context);
}
@Override
public void resolveDependencies(Resolver resolver)
{
resolver.markDependency(this.baseModel);
}
/* A vérifier, pas sûr sûr de celle là Y-Y */
private ModelRenderProperties getRenderProperties(
ItemModel.BakingContext context)
{
ModelBaker modelbaker = context.blockModelBaker();
ResolvedModel resolvedmodel = modelbaker.getModel(this.baseModel);
TextureSlots textureslots = resolvedmodel.getTopTextureSlots();
return ModelRenderProperties.fromResolvedModel(modelbaker,
resolvedmodel, textureslots);
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 B