feat: flower_crown composite model
Some checks are pending
Build / build (push) Waiting to run

This commit is contained in:
SushiCannibale 2025-08-12 22:14:54 +02:00
parent f73affdb2c
commit 9bcabeb8f7
10 changed files with 61 additions and 13 deletions

View file

@ -4,6 +4,8 @@ import com.mojang.math.Transformation;
import com.mojang.serialization.MapCodec; import com.mojang.serialization.MapCodec;
import com.mojang.serialization.codecs.RecordCodecBuilder; import com.mojang.serialization.codecs.RecordCodecBuilder;
import fr.sushi.charmsnfabrics.CharmsAndFabrics; import fr.sushi.charmsnfabrics.CharmsAndFabrics;
import fr.sushi.charmsnfabrics.common.CnFRegistries;
import fr.sushi.charmsnfabrics.common.data.SavedColors;
import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.block.model.BakedQuad;
@ -14,6 +16,7 @@ import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.model.*; import net.minecraft.client.resources.model.*;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.DyeColor;
import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.neoforged.neoforge.client.ClientHooks; import net.neoforged.neoforge.client.ClientHooks;
@ -26,14 +29,49 @@ import org.joml.Quaternionf;
import org.joml.Vector3f; import org.joml.Vector3f;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
public class FlowerCrownItemModel implements ItemModel public class FlowerCrownItemModel implements ItemModel
{ {
/* TODO: Center flower0&1 textures and play with transform to get them at the right place for every layer */ /* TODO: Center flower0&1 textures and play with transform to get them at the right place for every layer */
private static final Transformation TRANSFORM =
new Transformation(new Vector3f(), new Quaternionf(), private static final Map<Integer, Transformation> TRANSFORMS =
new Vector3f(1.0f, 1.0f, 1.004f), new Quaternionf()); new HashMap<>();
static
{
TRANSFORMS.put(0, new Transformation(
new Vector3f(1f * 0.0625f, -4f * 0.0625f, 0.0f),
new Quaternionf(), new Vector3f(1.01f, 1.01f, 1.0625f),
new Quaternionf()));
TRANSFORMS.put(1, new Transformation(
new Vector3f(5f * 0.0625f, -3f * 0.0625f, 0.0f),
new Quaternionf(), new Vector3f(1.01f, 1.01f, 1.0625f),
new Quaternionf()));
TRANSFORMS.put(2, new Transformation(
new Vector3f(5f * 0.0625f, 2f * 0.0625f, 0.0f),
new Quaternionf(), new Vector3f(1.01f, 1.01f, 1.0625f),
new Quaternionf()));
TRANSFORMS.put(3, new Transformation(
new Vector3f(2f * 0.0625f, 4f * 0.0625f, 0.0f),
new Quaternionf(), new Vector3f(1.01f, 1.01f, 1.0625f),
new Quaternionf()));
TRANSFORMS.put(4, new Transformation(
new Vector3f(-3f * 0.0625f, 4f * 0.0625f, 0.0f),
new Quaternionf(), new Vector3f(1.01f, 1.01f, 1.0625f),
new Quaternionf()));
TRANSFORMS.put(5, new Transformation(
new Vector3f(-5f * 0.0625f, 0f * 0.0625f, 0.0f),
new Quaternionf(), new Vector3f(1.01f, 1.01f, 1.0625f),
new Quaternionf()));
TRANSFORMS.put(6, new Transformation(
new Vector3f(-4f * 0.0625f, -3f * 0.0625f, 0.0f),
new Quaternionf(), new Vector3f(1.01f, 1.01f, 1.0625f),
new Quaternionf()));
}
private static final ModelDebugName DEBUG_NAME = private static final ModelDebugName DEBUG_NAME =
() -> "FlowerCrownItemModel"; () -> "FlowerCrownItemModel";
@ -49,8 +87,9 @@ public class FlowerCrownItemModel implements ItemModel
private ResourceLocation getFlowerLocation(int layer) private ResourceLocation getFlowerLocation(int layer)
{ {
return ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID, return ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID,
"flower/flower" + layer); "flower/flower_" + (layer % 2 == 0 ? "large" : "small"));
} }
private static RenderTypeGroup getLayerRenderTypes(boolean unlit) private static RenderTypeGroup getLayerRenderTypes(boolean unlit)
@ -78,7 +117,7 @@ public class FlowerCrownItemModel implements ItemModel
return new BlockModelWrapper(List.of(), quads, this.renderProperties); return new BlockModelWrapper(List.of(), quads, this.renderProperties);
} }
private ItemModel bakeLayer(int layer) private ItemModel bakeLayer(int layer, DyeColor color)
{ {
SpriteGetter sprites = this.context.blockModelBaker().sprites(); SpriteGetter sprites = this.context.blockModelBaker().sprites();
Material material = Material material =
@ -90,15 +129,18 @@ public class FlowerCrownItemModel implements ItemModel
List<BakedQuad> quads = List<BakedQuad> quads =
UnbakedElementsHelper.bakeElements(bits, $ -> sprite, UnbakedElementsHelper.bakeElements(bits, $ -> sprite,
new ComposedModelState(BlockModelRotation.X0_Y0, new ComposedModelState(BlockModelRotation.X0_Y0,
TRANSFORM)); TRANSFORMS.get(layer)));
return new BlockModelWrapper(List.of(), quads, this.renderProperties); return new BlockModelWrapper(List.of(), quads, this.renderProperties);
} }
private CompositeModel composeModel() private ItemModel composeModel(SavedColors colors)
{ {
List<ItemModel> models = new ArrayList<>(); List<ItemModel> models = new ArrayList<>();
models.add(this.bakeBase()); models.add(this.bakeBase());
models.add(this.bakeLayer(0)); for (int i = 0; i < colors.flowers().size(); i++)
{
models.add(this.bakeLayer(i, colors.flowers().get(i)));
}
return new CompositeModel(models); return new CompositeModel(models);
} }
@ -108,7 +150,13 @@ public class FlowerCrownItemModel implements ItemModel
ItemDisplayContext displayContext, @Nullable ClientLevel level, ItemDisplayContext displayContext, @Nullable ClientLevel level,
@Nullable LivingEntity entity, int seed) @Nullable LivingEntity entity, int seed)
{ {
this.composeModel() SavedColors comp =
stack.get(CnFRegistries.DataComponents.SAVED_FLOWERS.get());
if (comp == null)
{
comp = new SavedColors(List.of());
}
this.composeModel(comp)
.update(renderState, stack, itemModelResolver, displayContext, .update(renderState, stack, itemModelResolver, displayContext,
level, entity, seed); level, entity, seed);
} }
@ -116,11 +164,11 @@ public class FlowerCrownItemModel implements ItemModel
public record Unbaked(ResourceLocation base) implements ItemModel.Unbaked public record Unbaked(ResourceLocation base) implements ItemModel.Unbaked
{ {
public static final MapCodec<FlowerCrownItemModel.Unbaked> MAP_CODEC = public static final MapCodec<Unbaked> MAP_CODEC =
RecordCodecBuilder.mapCodec(unbaked -> unbaked RecordCodecBuilder.mapCodec(unbaked -> unbaked
.group(ResourceLocation.CODEC.fieldOf("base").forGetter( .group(ResourceLocation.CODEC.fieldOf("base")
FlowerCrownItemModel.Unbaked::base)) .forGetter(Unbaked::base))
.apply(unbaked, FlowerCrownItemModel.Unbaked::new)); .apply(unbaked, Unbaked::new));
@Override @Override
public MapCodec<? extends ItemModel.Unbaked> type() public MapCodec<? extends ItemModel.Unbaked> type()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B