diff --git a/fabric-rendering-v1/build.gradle b/fabric-rendering-v1/build.gradle index ef0e58c3d6..ac1ae68672 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 0000000000..82719276f8 --- /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}. + * + *

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.

+ * + *

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.

+ * + *

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.

+ */ +@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 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 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 getArmorModel(LivingEntity entity, ItemStack stack, EquipmentSlot slot, BipedEntityModel 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 getArmorModel(LivingEntity entity, ItemStack stack, EquipmentSlot slot, BipedEntityModel 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 0000000000..13166aa39f --- /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 0000000000..4bd3a91e61 --- /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 items) { + Objects.requireNonNull(items); + + for (Item item : items) { + Objects.requireNonNull(item); + + ((ArmorProviderExtensions) item).fabric_setArmorModelProvider(provider); + } + } + + public static void registerTexture(ArmorRenderingRegistry.TextureProvider provider, Iterable items) { + Objects.requireNonNull(items); + + for (Item item : items) { + Objects.requireNonNull(item); + + ((ArmorProviderExtensions) item).fabric_setArmorTextureProvider(provider); + } + } + + public static BipedEntityModel getArmorModel(LivingEntity entity, ItemStack stack, EquipmentSlot slot, BipedEntityModel 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 0000000000..55d646657e --- /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 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> cir) { + ItemStack stack = storedEntity.getEquippedStack(slot); + + BipedEntityModel defaultModel = cir.getReturnValue(); + BipedEntityModel 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 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 0000000000..7d3fc300b8 --- /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 aad088181d..3f55d6a8ac 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 0000000000..b2311eac97 --- /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 0000000000..db22faad67 --- /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 { + 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 getBodyParts() { + return Collections.singleton(part); + } + + @Override + protected Iterable 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 0000000000..6ae593cc53 Binary files /dev/null and b/fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/cube.png differ 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 0000000000..d4bcbb9d68 Binary files /dev/null and b/fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/custom_texture.png differ 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 0000000000..e29f81a2a3 Binary files /dev/null and b/fabric-rendering-v1/src/testmod/resources/assets/fabric-rendering-v1-testmod/textures/models/armor/simple_textured_armor_layer_1.png differ 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 0000000000..342edb10e6 --- /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" + ] + } +}