diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/model/FlowerCrownItemModel.java b/src/main/java/fr/sushi/charmsnfabrics/client/model/FlowerCrownItemModel.java new file mode 100644 index 0000000..69fe5df --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/client/model/FlowerCrownItemModel.java @@ -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 colors) + { + ModelState state = BlockModelRotation.X0_Y0; + SpriteGetter sprites = this.bakingContext.blockModelBaker().sprites(); + + List 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 unbaked = + UnbakedElementsHelper.createUnbakedItemElements(0, sprite); + List 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 MAP_CODEC = + RecordCodecBuilder.mapCodec(unbaked -> unbaked + .group(ResourceLocation.CODEC.fieldOf("base").forGetter( + FlowerCrownItemModel.Unbaked::baseModel)) + .apply(unbaked, FlowerCrownItemModel.Unbaked::new)); + + @Override + public MapCodec type() + { + return MAP_CODEC; + } + + @Override + public ItemModel bake(BakingContext context) + { + ModelBaker modelbaker = context.blockModelBaker(); + ResolvedModel resolved = modelbaker.getModel(this.baseModel); + List 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); + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/charmsnfabrics/textures/flowers/flower0.png b/src/main/resources/assets/charmsnfabrics/textures/flowers/flower0.png new file mode 100644 index 0000000..4d44cd0 Binary files /dev/null and b/src/main/resources/assets/charmsnfabrics/textures/flowers/flower0.png differ