From f21864f86dca7213fe35d73007f64d0b12673bce Mon Sep 17 00:00:00 2001 From: shedaniel <daniel@shedaniel.me> Date: Mon, 16 Nov 2020 03:07:24 +0800 Subject: [PATCH] fabric-rendering-v1: Custom Armor Model & Texture (#963) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Moving testmod id to rendering-v1 Signed-off-by: shedaniel <daniel@shedaniel.me> Moving testmod to rendering-v1 Signed-off-by: shedaniel <daniel@shedaniel.me> Reviews Signed-off-by: shedaniel <daniel@shedaniel.me> prefix the extensions with armor Signed-off-by: shedaniel <daniel@shedaniel.me> change name Signed-off-by: shedaniel <daniel@shedaniel.me> drop custom Signed-off-by: shedaniel <daniel@shedaniel.me> thing Signed-off-by: shedaniel <daniel@shedaniel.me> javadocs Signed-off-by: shedaniel <daniel@shedaniel.me> fix imports Signed-off-by: shedaniel <daniel@shedaniel.me> forgot to do asItem Signed-off-by: shedaniel <daniel@shedaniel.me> add null checks and convert to ItemConvertible Signed-off-by: shedaniel <daniel@shedaniel.me> fix license Signed-off-by: shedaniel <daniel@shedaniel.me> did thing Signed-off-by: shedaniel <daniel@shedaniel.me> it now compiles Signed-off-by: shedaniel <daniel@shedaniel.me> change to a registry Signed-off-by: shedaniel <daniel@shedaniel.me> add @Unique Signed-off-by: shedaniel <daniel@shedaniel.me> migrate to fabric-item-api-v1 Signed-off-by: shedaniel <daniel@shedaniel.me> did some renaming and improvements Signed-off-by: shedaniel <daniel@shedaniel.me> don't need that Signed-off-by: shedaniel <daniel@shedaniel.me> armor Signed-off-by: shedaniel <daniel@shedaniel.me> * add license to CustomArmorTests Signed-off-by: shedaniel <daniel@shedaniel.me> * Add @Nullable annotations and fix compile Signed-off-by: shedaniel <daniel@shedaniel.me> * javadoc Signed-off-by: shedaniel <daniel@shedaniel.me> * Fix reviews Signed-off-by: shedaniel <daniel@shedaniel.me> * Update fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinArmorFeatureRenderer.java Co-authored-by: Erlend Åmdal <erlend@aamdal.com> * Add registerSimpleTexture Pass through secondLayer and suffix Use Identifier's over strings Fix the test mod * license fix Co-authored-by: Erlend Åmdal <erlend@aamdal.com> Co-authored-by: modmuss50 <modmuss50@gmail.com> --- fabric-rendering-v1/build.gradle | 2 +- .../rendering/v1/ArmorRenderingRegistry.java | 165 ++++++++++++++++++ .../rendering/ArmorProviderExtensions.java | 33 ++++ .../rendering/ArmorRenderingRegistryImpl.java | 79 +++++++++ .../rendering/MixinArmorFeatureRenderer.java | 103 +++++++++++ .../mixin/client/rendering/MixinItem.java | 53 ++++++ .../resources/fabric-rendering-v1.mixins.json | 2 + .../test/rendering/CustomArmorTests.java | 45 +++++ .../client/CustomArmorTestsClient.java | 68 ++++++++ .../textures/cube.png | Bin 0 -> 471 bytes .../textures/custom_texture.png | Bin 0 -> 670 bytes .../armor/simple_textured_armor_layer_1.png | Bin 0 -> 141 bytes .../src/testmod/resources/fabric.mod.json | 19 ++ 13 files changed, 568 insertions(+), 1 deletion(-) create mode 100644 fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/ArmorRenderingRegistry.java create mode 100644 fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/ArmorProviderExtensions.java create mode 100644 fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/ArmorRenderingRegistryImpl.java create mode 100644 fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinArmorFeatureRenderer.java create mode 100644 fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinItem.java create mode 100644 fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/CustomArmorTests.java create mode 100644 fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/client/CustomArmorTestsClient.java create mode 100644 fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/cube.png create mode 100644 fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/custom_texture.png create mode 100644 fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/models/armor/simple_textured_armor_layer_1.png create mode 100644 fabric-rendering-v1/src/testmod/resources/fabric.mod.json diff --git a/fabric-rendering-v1/build.gradle b/fabric-rendering-v1/build.gradle index ef0e58c3d..ac1ae6867 100644 --- a/fabric-rendering-v1/build.gradle +++ b/fabric-rendering-v1/build.gradle @@ -1,5 +1,5 @@ archivesBaseName = "fabric-rendering-v1" -version = getSubprojectVersion(project, "1.3.1") +version = getSubprojectVersion(project, "1.4.0") dependencies { compile project(path: ':fabric-api-base', configuration: 'dev') diff --git a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/ArmorRenderingRegistry.java b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/ArmorRenderingRegistry.java new file mode 100644 index 000000000..82719276f --- /dev/null +++ b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/api/client/rendering/v1/ArmorRenderingRegistry.java @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.api.client.rendering.v1; + +import java.util.Arrays; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.Identifier; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.impl.client.rendering.ArmorRenderingRegistryImpl; + +/** + * A class for registering custom armor models and textures for {@link Item}, to be provided by a {@link ModelProvider} or {@link TextureProvider}. + * + * <p>This can be used to replace existing vanilla armor models and textures conditionally, however each {@link Item} + * instance can only allow one {@link ModelProvider} or {@link TextureProvider} respectively, causing potential conflicts + * with other mods if you replace the model or texture for vanilla items. Consider using a separate item instead.</p> + * + * <p>A custom model would probably also require a custom texture to go along it, the model will use the vanilla texture if it is undefined.</p> + * + * <p>Since armor textures identifier in vanilla is hardcoded to be in the {@code minecraft} namespace, this registry can also be + * used to use a custom namespace if desired.</p> + */ +@Environment(EnvType.CLIENT) +public final class ArmorRenderingRegistry { + private ArmorRenderingRegistry() { + } + + /** + * Registers a provider for custom armor models for an item. + * + * @param provider the provider for the model + * @param items the items to be registered for + */ + public static void registerModel(@Nullable ModelProvider provider, Item... items) { + registerModel(provider, Arrays.asList(items)); + } + + /** + * Registers a provider for custom armor models for an item. + * + * @param provider the provider for the model + * @param items the items to be registered for + */ + public static void registerModel(@Nullable ModelProvider provider, Iterable<Item> items) { + ArmorRenderingRegistryImpl.registerModel(provider, items); + } + + /** + * Registers a provider for custom texture models for an item. + * + * @param provider the provider for the texture + * @param items the items to be registered for + */ + public static void registerTexture(@Nullable TextureProvider provider, Item... items) { + registerTexture(provider, Arrays.asList(items)); + } + + /** + * Registers a provider for custom texture models for an item. + * + * @param provider the provider for the texture + * @param items the items to be registered for + */ + public static void registerTexture(@Nullable TextureProvider provider, Iterable<Item> items) { + ArmorRenderingRegistryImpl.registerTexture(provider, items); + } + + /** + * Register simple armor items to use the vanilla armor file name under the mods namespace. + * + * @param identifier The namespace + path to use for the armor texture location. + * @param items the items to be registered + */ + public static void registerSimpleTexture(Identifier identifier, Item... items) { + registerTexture((entity, stack, slot, secondLayer, suffix, defaultTexture) -> { + return new Identifier(identifier.getNamespace(), "textures/models/armor/" + identifier.getPath() + "_layer_" + (secondLayer ? 2 : 1) + (suffix == null ? "" : "_" + suffix) + ".png"); + }, items); + } + + /** + * Gets the model of the armor piece. + * + * @param entity The entity equipping the armor + * @param stack The item stack of the armor + * @param slot The slot which the armor is in + * @param defaultModel The default model that vanilla provides + * @return The model of the armor piece. + */ + @NotNull + public static BipedEntityModel<LivingEntity> getArmorModel(LivingEntity entity, ItemStack stack, EquipmentSlot slot, BipedEntityModel<LivingEntity> defaultModel) { + return ArmorRenderingRegistryImpl.getArmorModel(entity, stack, slot, defaultModel); + } + + /** + * Gets the armor texture {@link net.minecraft.util.Identifier}. + * + * @param entity The entity equipping the armor + * @param stack The item stack of the armor + * @param slot The slot which the armor is in + * @param secondLayer True if using the second texture layer + * @param suffix The texture suffix, used in vanilla by {@link net.minecraft.item.DyeableArmorItem} + * @param defaultTexture The default vanilla texture identifier + * @return the custom armor texture identifier, return null to use the vanilla ones. Defaulted to the item's registry id. + */ + @NotNull + public static Identifier getArmorTexture(LivingEntity entity, ItemStack stack, EquipmentSlot slot, boolean secondLayer, @Nullable String suffix, Identifier defaultTexture) { + return ArmorRenderingRegistryImpl.getArmorTexture(entity, stack, slot, secondLayer, suffix, defaultTexture); + } + + @FunctionalInterface + @Environment(EnvType.CLIENT) + public interface ModelProvider { + /** + * Gets the model of the armor piece. + * + * @param entity The entity equipping the armor + * @param stack The item stack of the armor + * @param slot The slot which the armor is in + * @param defaultModel The default vanilla armor model + * @return The model of the armor piece. Should never be null. + */ + @NotNull + BipedEntityModel<LivingEntity> getArmorModel(LivingEntity entity, ItemStack stack, EquipmentSlot slot, BipedEntityModel<LivingEntity> defaultModel); + } + + @FunctionalInterface + @Environment(EnvType.CLIENT) + public interface TextureProvider { + /** + * Gets the armor texture {@link net.minecraft.util.Identifier}. + * + * @param entity The entity equipping the armor + * @param stack The item stack of the armor + * @param slot The slot which the armor is in + * @param defaultTexture The default vanilla texture identifier + * @return the custom armor texture identifier. Should never be null. + */ + @NotNull + Identifier getArmorTexture(LivingEntity entity, ItemStack stack, EquipmentSlot slot, boolean secondLayer, @Nullable String suffix, Identifier defaultTexture); + } +} diff --git a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/ArmorProviderExtensions.java b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/ArmorProviderExtensions.java new file mode 100644 index 000000000..13166aa39 --- /dev/null +++ b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/ArmorProviderExtensions.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.impl.client.rendering; + +import org.jetbrains.annotations.Nullable; + +import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry; + +public interface ArmorProviderExtensions { + @Nullable + ArmorRenderingRegistry.ModelProvider fabric_getArmorModelProvider(); + + @Nullable + ArmorRenderingRegistry.TextureProvider fabric_getArmorTextureProvider(); + + void fabric_setArmorModelProvider(@Nullable ArmorRenderingRegistry.ModelProvider provider); + + void fabric_setArmorTextureProvider(@Nullable ArmorRenderingRegistry.TextureProvider provider); +} diff --git a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/ArmorRenderingRegistryImpl.java b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/ArmorRenderingRegistryImpl.java new file mode 100644 index 000000000..4bd3a91e6 --- /dev/null +++ b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/impl/client/rendering/ArmorRenderingRegistryImpl.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.impl.client.rendering; + +import java.util.Objects; + +import org.jetbrains.annotations.Nullable; + +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; + +import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry; + +public final class ArmorRenderingRegistryImpl { + private ArmorRenderingRegistryImpl() { + } + + public static void registerModel(ArmorRenderingRegistry.ModelProvider provider, Iterable<Item> items) { + Objects.requireNonNull(items); + + for (Item item : items) { + Objects.requireNonNull(item); + + ((ArmorProviderExtensions) item).fabric_setArmorModelProvider(provider); + } + } + + public static void registerTexture(ArmorRenderingRegistry.TextureProvider provider, Iterable<Item> items) { + Objects.requireNonNull(items); + + for (Item item : items) { + Objects.requireNonNull(item); + + ((ArmorProviderExtensions) item).fabric_setArmorTextureProvider(provider); + } + } + + public static BipedEntityModel<LivingEntity> getArmorModel(LivingEntity entity, ItemStack stack, EquipmentSlot slot, BipedEntityModel<LivingEntity> defaultModel) { + if (!stack.isEmpty()) { + ArmorRenderingRegistry.ModelProvider provider = ((ArmorProviderExtensions) stack.getItem()).fabric_getArmorModelProvider(); + + if (provider != null) { + return provider.getArmorModel(entity, stack, slot, defaultModel); + } + } + + return defaultModel; + } + + public static Identifier getArmorTexture(LivingEntity entity, ItemStack stack, EquipmentSlot slot, boolean secondLayer, @Nullable String suffix, Identifier defaultTexture) { + if (!stack.isEmpty()) { + ArmorRenderingRegistry.TextureProvider provider = ((ArmorProviderExtensions) stack.getItem()).fabric_getArmorTextureProvider(); + + if (provider != null) { + return provider.getArmorTexture(entity, stack, slot, secondLayer, suffix, defaultTexture); + } + } + + return defaultTexture; + } +} diff --git a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinArmorFeatureRenderer.java b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinArmorFeatureRenderer.java new file mode 100644 index 000000000..55d646657 --- /dev/null +++ b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinArmorFeatureRenderer.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.client.rendering; + +import java.util.Map; +import java.util.Objects; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.feature.ArmorFeatureRenderer; +import net.minecraft.client.render.entity.feature.FeatureRenderer; +import net.minecraft.client.render.entity.feature.FeatureRendererContext; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry; + +@Mixin(ArmorFeatureRenderer.class) +@Environment(EnvType.CLIENT) +public abstract class MixinArmorFeatureRenderer extends FeatureRenderer { + @Shadow + @Final + private static Map<String, Identifier> ARMOR_TEXTURE_CACHE; + + public MixinArmorFeatureRenderer(FeatureRendererContext context) { + super(context); + } + + @Unique + private LivingEntity storedEntity; + @Unique + private EquipmentSlot storedSlot; + + @Inject(method = "render", at = @At("HEAD")) + private void storeEntity(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, LivingEntity livingEntity, float f, float g, float h, float j, float k, float l, CallbackInfo ci) { + // We store the living entity wearing the armor before we render + this.storedEntity = livingEntity; + } + + @Inject(method = "renderArmor", at = @At("HEAD")) + private void storeSlot(MatrixStack matrices, VertexConsumerProvider vertexConsumers, LivingEntity livingEntity, EquipmentSlot slot, int i, BipedEntityModel bipedEntityModel, CallbackInfo ci) { + // We store the current armor slot that is rendering before we render each armor piece + this.storedSlot = slot; + } + + @Inject(method = "render", at = @At("RETURN")) + private void removeStored(MatrixStack matrixStack, VertexConsumerProvider vertexConsumerProvider, int i, LivingEntity livingEntity, float f, float g, float h, float j, float k, float l, CallbackInfo ci) { + // We remove the stored data after we render + this.storedEntity = null; + this.storedSlot = null; + } + + @Inject(method = "getArmor", at = @At("RETURN"), cancellable = true) + private void selectArmorModel(EquipmentSlot slot, CallbackInfoReturnable<BipedEntityModel<LivingEntity>> cir) { + ItemStack stack = storedEntity.getEquippedStack(slot); + + BipedEntityModel<LivingEntity> defaultModel = cir.getReturnValue(); + BipedEntityModel<LivingEntity> model = ArmorRenderingRegistry.getArmorModel(storedEntity, stack, slot, defaultModel); + + if (model != defaultModel) { + cir.setReturnValue(model); + } + } + + @Inject(method = "getArmorTexture", at = @At(value = "INVOKE", target = "Ljava/util/Map;computeIfAbsent(Ljava/lang/Object;Ljava/util/function/Function;)Ljava/lang/Object;"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD) + private void getArmorTexture(ArmorItem armorItem, boolean secondLayer, /* @Nullable */ String suffix, CallbackInfoReturnable<Identifier> cir, String vanillaIdentifier) { + String texture = ArmorRenderingRegistry.getArmorTexture(storedEntity, storedEntity.getEquippedStack(storedSlot), storedSlot, secondLayer, suffix, new Identifier(vanillaIdentifier)).toString(); + + if (!Objects.equals(texture, vanillaIdentifier)) { + cir.setReturnValue(ARMOR_TEXTURE_CACHE.computeIfAbsent(texture, Identifier::new)); + } + } +} diff --git a/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinItem.java b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinItem.java new file mode 100644 index 000000000..7d3fc300b --- /dev/null +++ b/fabric-rendering-v1/src/main/java/net/fabricmc/fabric/mixin/client/rendering/MixinItem.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.mixin.client.rendering; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +import net.minecraft.item.Item; + +import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry; +import net.fabricmc.fabric.impl.client.rendering.ArmorProviderExtensions; + +@Mixin(Item.class) +public class MixinItem implements ArmorProviderExtensions { + @Unique + private ArmorRenderingRegistry.ModelProvider armorModelProvider; + @Unique + private ArmorRenderingRegistry.TextureProvider armorTextureProvider; + + @Override + public ArmorRenderingRegistry.ModelProvider fabric_getArmorModelProvider() { + return armorModelProvider; + } + + @Override + public ArmorRenderingRegistry.TextureProvider fabric_getArmorTextureProvider() { + return armorTextureProvider; + } + + @Override + public void fabric_setArmorModelProvider(ArmorRenderingRegistry.ModelProvider provider) { + armorModelProvider = provider; + } + + @Override + public void fabric_setArmorTextureProvider(ArmorRenderingRegistry.TextureProvider provider) { + armorTextureProvider = provider; + } +} diff --git a/fabric-rendering-v1/src/main/resources/fabric-rendering-v1.mixins.json b/fabric-rendering-v1/src/main/resources/fabric-rendering-v1.mixins.json index aad088181..3f55d6a8a 100644 --- a/fabric-rendering-v1/src/main/resources/fabric-rendering-v1.mixins.json +++ b/fabric-rendering-v1/src/main/resources/fabric-rendering-v1.mixins.json @@ -3,9 +3,11 @@ "package": "net.fabricmc.fabric.mixin.client.rendering", "compatibilityLevel": "JAVA_8", "client": [ + "MixinArmorFeatureRenderer", "MixinBlockColorMap", "MixinBuiltinModelItemRenderer", "MixinInGameHud", + "MixinItem", "MixinItemColorMap", "MixinWorldRenderer" ], diff --git a/fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/CustomArmorTests.java b/fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/CustomArmorTests.java new file mode 100644 index 000000000..b2311eac9 --- /dev/null +++ b/fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/CustomArmorTests.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.test.rendering; + +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.item.ArmorItem; +import net.minecraft.item.ArmorMaterials; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +import net.fabricmc.api.ModInitializer; + +public class CustomArmorTests implements ModInitializer { + public static Item customModeledArmor; + public static Item customTexturedArmor; + public static Item simpleTexturedArmor; + + @Override + public void onInitialize() { + Registry.register(Registry.ITEM, new Identifier("fabric-rendering-v1-testmod:custom_modeled_armor"), + customModeledArmor = new ArmorItem(ArmorMaterials.DIAMOND, EquipmentSlot.CHEST, new Item.Settings().group(ItemGroup.COMBAT))); + + Registry.register(Registry.ITEM, new Identifier("fabric-rendering-v1-testmod:custom_textured_armor"), + customTexturedArmor = new ArmorItem(ArmorMaterials.DIAMOND, EquipmentSlot.CHEST, new Item.Settings().group(ItemGroup.COMBAT))); + + Registry.register(Registry.ITEM, new Identifier("fabric-rendering-v1-testmod:simple_textured_armor"), + simpleTexturedArmor = new ArmorItem(ArmorMaterials.DIAMOND, EquipmentSlot.CHEST, new Item.Settings().group(ItemGroup.COMBAT))); + } +} diff --git a/fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/client/CustomArmorTestsClient.java b/fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/client/CustomArmorTestsClient.java new file mode 100644 index 000000000..db22faad6 --- /dev/null +++ b/fabric-rendering-v1/src/testmod/java/net/fabricmc/fabric/test/rendering/client/CustomArmorTestsClient.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2016, 2017, 2018, 2019 FabricMC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package net.fabricmc.fabric.test.rendering.client; + +import java.util.Collections; + +import net.minecraft.client.model.ModelPart; +import net.minecraft.client.render.entity.model.BipedEntityModel; +import net.minecraft.entity.LivingEntity; +import net.minecraft.util.Identifier; + +import net.fabricmc.api.ClientModInitializer; +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.fabricmc.fabric.api.client.rendering.v1.ArmorRenderingRegistry; +import net.fabricmc.fabric.test.rendering.CustomArmorTests; + +@Environment(EnvType.CLIENT) +public class CustomArmorTestsClient implements ClientModInitializer { + @Override + public void onInitializeClient() { + CustomArmorModel model = new CustomArmorModel(1.0F); + ArmorRenderingRegistry.registerModel((entity, stack, slot, defaultModel) -> model, CustomArmorTests.customModeledArmor); + ArmorRenderingRegistry.registerTexture((entity, stack, slot, secondLayer, suffix, defaultTexture) -> + new Identifier("fabric-rendering-v1-testmod", "textures/cube.png"), CustomArmorTests.customModeledArmor); + + ArmorRenderingRegistry.registerTexture((entity, stack, slot, secondLayer, suffix, defaultTexture) -> + new Identifier("fabric-rendering-v1-testmod", "textures/custom_texture.png"), CustomArmorTests.customTexturedArmor); + + ArmorRenderingRegistry.registerSimpleTexture(new Identifier("fabric-rendering-v1-testmod", "simple_textured_armor"), CustomArmorTests.simpleTexturedArmor); + } + + private static class CustomArmorModel extends BipedEntityModel<LivingEntity> { + private final ModelPart part; + + CustomArmorModel(float scale) { + super(scale, 0, 1, 1); + part = new ModelPart(this, 0, 0); + part.addCuboid(-5F, 0F, 2F, 10, 10, 10); + part.setPivot(0F, 0F, 0F); + part.mirror = true; + } + + @Override + protected Iterable<ModelPart> getBodyParts() { + return Collections.singleton(part); + } + + @Override + protected Iterable<ModelPart> getHeadParts() { + return Collections::emptyIterator; + } + } +} diff --git a/fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/cube.png b/fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/cube.png new file mode 100644 index 0000000000000000000000000000000000000000..6ae593cc53ce949e1a8649fde3e7646a6f28c038 GIT binary patch literal 471 zcmV;|0Vw{7P)<h;3K|Lk000e1NJLTq00031000391^@s69~H!j0004nX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iQ%gmv4t5afkf92K1yK=4twIqhlv<%x2a`*`ph-iL z;^HW{799LotU9<j>+0Yt2!bCVPL58BE>hzEl0u6Z503ls?%w0>9UwF+Of|d40ade% zbRsThbE{(T6+uMMhX6(;X6kdPR1%)!>mEM7-o<#9_qjhuuaY+z;1h{wnQmCb8^qI_ zmd<&fILu0tLVQj<X3zzRAGt2O{KmQHu)s6JMkYN^93~cv9V~Y+D;X;B6me8hHOd#V zE-Re3IIEQ!Yu%H-FqGF;mbp$df&><^gcL-`sG*DsEW~KlNHLM7{kVsJ$nmGhC6lWR zMvetkp+a)};D7MDTeC1Z;U<ORK;Xr;KZb$eF3_yo_V=-EH%|cnGjOG~{nZ9A^GSNW ztwoQ3{%zpmx~<83z~v4w_@qmQ<Vb#+LZJY>pV2qvfPq_}XU*-cwU5&WAVXaxZ-9eC zV5CUd>mKj!?(FT~Gp+u909T}PoD`t}ga7~l4M{{nR0x@4U|?YQ4*&rK0RVln$lm|} N002ovPDHLkV1gW6&L98) literal 0 HcmV?d00001 diff --git a/fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/custom_texture.png b/fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/custom_texture.png new file mode 100644 index 0000000000000000000000000000000000000000..d4bcbb9d681d3829bdb1ff36f56a25deedad4362 GIT binary patch literal 670 zcmV;P0%84$P)<h;3K|Lk000e1NJLTq002M$001Be1^@s6qMd$(0004nX+uL$Nkc;* zaB^>EX>4Tx04R}tkv&MmKpe$iQ%gmv4t5afkf92K1yK=4twIqhlv<%x2a`*`ph-iL z;^HW{799LotU9<j>+0Yt2!bCVPL58BE>hzEl0u6Z503ls?%w0>9UwF+Of|d40ade% zbRsThbE{(T6+uMMhX6(;X6kdPR1%)!>mEM7-o<#9_qjhuuaY+z;1h{wnQmCb8^qI_ zmd<&fILu0tLVQj<X3zzRAGt2O{KmQHu)s6JMkYN^93~cv9V~Y+D;X;B6me8hHOd#V zE-Re3IIEQ!Yu%H-FqGF;mbp$df&><^gcL-`sG*DsEW~KlNHLM7{kVsJ$nmGhC6lWR zMvetkp+a)};D7MDTeC1Z;U<ORK;Xr;KZb$eF3_yo_V=-EH%|cnGjOG~{nZ9A^GSNW ztwoQ3{%zpmx~<83z~v4w_@qmQ<Vb#+LZJY>pV2qvfPq_}XU*-cwU5&WAVXaxZ-9eC zV5CUd>mKj!?(FT~Gp+u909T}PoD`t}ga7~l24YJ`L;(K)0000pCw%h&000SaNLh0L z04^f{04^f|c%?sf00007bV*G`2jmAF4hJU*JISR0000?uMObu0Z*6U5Zgc=ca%Ew3 zWn>_CX>@2HM@dakSAh-}0001WNkl<ZXx{DAOAde_3`NmCc2f7hCRs|InizFJFx1{N zBWd_NC}scv0000004mYw1nwT^@!tDm{pN1B^)j=#Y)~@;XiHs3e7|H{_;F<qAX4Pj zDnI}A{s02_Qvj+SK;#HO6V4qk3u>f3*B_wDEs&%Q4j^F>7TA@Z<NyEw07*qoM6N<$ Ef}DjGBme*a literal 0 HcmV?d00001 diff --git a/fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/models/armor/simple_textured_armor_layer_1.png b/fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/models/armor/simple_textured_armor_layer_1.png new file mode 100644 index 0000000000000000000000000000000000000000..e29f81a2a3de238ab2d8d04b9674533e82b05912 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^4nVBH!VDw>HYaZfQjEnx?oJHr&dIz4a#+$GeH|GX zHuiJ>Nn{1`nFD-6TzzW(7Zgq41adhGJR*x382Ao@Fyrz36)8YLVNVyw5R22v60D08 gM0%LkG&C|YuqZGvJ{NPc1WGe_y85}Sb4q9e0F2Qgp8x;= literal 0 HcmV?d00001 diff --git a/fabric-rendering-v1/src/testmod/resources/fabric.mod.json b/fabric-rendering-v1/src/testmod/resources/fabric.mod.json new file mode 100644 index 000000000..342edb10e --- /dev/null +++ b/fabric-rendering-v1/src/testmod/resources/fabric.mod.json @@ -0,0 +1,19 @@ +{ + "schemaVersion": 1, + "id": "fabric-rendering-v1-testmod", + "name": "Fabric Rendering (v1) Test Mod", + "version": "1.0.0", + "environment": "*", + "license": "Apache-2.0", + "depends": { + "fabric-rendering-v1": "*" + }, + "entrypoints": { + "main": [ + "net.fabricmc.fabric.test.rendering.CustomArmorTests" + ], + "client": [ + "net.fabricmc.fabric.test.rendering.client.CustomArmorTestsClient" + ] + } +}