Overview
The Block and Item Layer feature allows you to easily render blocks and item stacks onto predefined bones of a model using AzureLib's rendering pipeline.
The AzBlockAndItemLayer handles the rendering logic for these elements by:
- Applying transformations specific to the bones associated with items/blocks.
- Rendering the correct visuals for items and blocks by using Minecraft’s rendering utilities.
Setup Instructions
Step 1: Add the Block and Item Layer to Your Renderer
Adding the AzBlockAndItemLayer to your renderer is straightforward. Use the addRenderLayer() method to register the layer in your entity renderer's configuration. Below is an example configuration:
public class ExampleEntityRenderer extends AzEntityRenderer<ExampleEntity> {private static final ResourceLocation MODEL_LOCATION =ResourceLocation.fromNamespaceAndPath("yourmodid", "geo/example_model.geo.json");private static final ResourceLocation TEXTURE_LOCATION =ResourceLocation.fromNamespaceAndPath("yourmodid", "textures/entity/example_model.png");public ExampleEntityRenderer(EntityRendererProvider.Context context) {super(AzEntityRendererConfig.<ExampleEntity>builder(MODEL_LOCATION, TEXTURE_LOCATION).addRenderLayer(new AzBlockAndItemLayer<ExampleEntity>() {// Override methods here}).build(),context);}}
Step 3: Customize Bone-Item Relationships
The AzBlockAndItemLayer provides several methods to define relationships between bones and the items or blocks they render:
-
itemStackForBone:- Associates an
ItemStackwith a specific bone. - In the example,
rightHandBoneandleftHandBoneare linked to the main and off-hand slots of the entity.
@Overridepublic ItemStack itemStackForBone(AzBone bone, ExampleEntity animatable) {return switch (bone.getName()) {case "rightHandBone" -> animatable.getItemBySlot(EquipmentSlot.MAINHAND);case "leftHandBone" -> animatable.getItemBySlot(EquipmentSlot.OFFHAND);default -> null;};} - Associates an
-
getTransformTypeForStack:- Determines the display context for rendering items.
- For example:
ItemDisplayContext.THIRD_PERSON_RIGHT_HANDfor the right hand.ItemDisplayContext.THIRD_PERSON_LEFT_HANDfor the left hand.
@Overrideprotected ItemDisplayContext getTransformTypeForStack(AzBone bone, ItemStack stack, ExampleEntity animatable) {return switch (bone.getName()) {case "rightHandBone" -> ItemDisplayContext.THIRD_PERSON_RIGHT_HAND;case "leftHandBone" -> ItemDisplayContext.THIRD_PERSON_LEFT_HAND;default -> ItemDisplayContext.NONE;};} -
renderItemForBone:- Applies specific transformations for the item before rendering.
- In the example:
- A rotation of 270° is applied to align the item correctly.
- The position is adjusted with a small translation.
@Overrideprotected void renderItemForBone(AzRendererPipelineContext<UUID, ExampleEntity> context, AzBone bone, ItemStack itemStack, ExampleEntity animatable) {context.poseStack().mulPose(Axis.XP.rotationDegrees(270));context.poseStack().translate(0.0D, 0.1D, -0.1D);super.renderItemForBone(context, bone, itemStack, animatable);} -
renderBlockForBone:- Similar to
renderItemForBone, but handlesBlockStaterendering instead of items. - Adjustments are made to ensure the block fits naturally within the bone space:
- A default scaling factor of
0.5freduces the block to an appropriate size.
- A default scaling factor of
@Overrideprotected void renderBlockForBone(AzRendererPipelineContext<UUID, ExampleEntity> context, AzBone bone, BlockState blockState, ExampleEntity animatable) {context.poseStack().pushPose();context.poseStack().translate(-0.25f, -0.25f, -0.25f);context.poseStack().scale(0.5f, 0.5f, 0.5f);super.renderBlockForBone(context, bone, blockState, animatable);} - Similar to
Example Use Case
Scenario: Say you have an entity model where the right hand holds a sword, and the left hand holds a shield.
- Define bones in your model called
rightHandBoneandleftHandBone. - Associate the bones with your entity's inventory slots using
itemStackForBone. - Set the appropriate display context for each bone with
getTransformTypeForStack. - Apply specific pose adjustments for how the item should look when held using
renderItemForBone.
By following these steps, the entity model will dynamically render the correct items or blocks held in its hands, fully animated and interacting with your AzureLib model.
public class ExampleEntityRenderer extends AzEntityRenderer<ExampleEntity> {private static final ResourceLocation MODEL_LOCATION =ResourceLocation.fromNamespaceAndPath("yourmodid", "geo/example_model.geo.json");private static final ResourceLocation TEXTURE_LOCATION =ResourceLocation.fromNamespaceAndPath("yourmodid", "textures/entity/example_model.png");public ExampleEntityRenderer(EntityRendererProvider.Context context) {super(AzEntityRendererConfig.<ExampleEntity>builder(MODEL_LOCATION, TEXTURE_LOCATION).addRenderLayer(new AzBlockAndItemLayer<ExampleEntity>() {@Overridepublic ItemStack itemStackForBone(AzBone bone, ExampleEntity animatable) {return switch (bone.getName()) {case "rightHandBone" -> animatable.getItemBySlot(EquipmentSlot.MAINHAND);case "leftHandBone" -> animatable.getItemBySlot(EquipmentSlot.OFFHAND);default -> null;};}@Overrideprotected ItemDisplayContext getTransformTypeForStack(AzBone bone, ItemStack stack, ExampleEntity animatable) {return switch (bone.getName()) {case "rightHandBone" -> ItemDisplayContext.THIRD_PERSON_RIGHT_HAND;case "leftHandBone" -> ItemDisplayContext.THIRD_PERSON_LEFT_HAND;default -> ItemDisplayContext.THIRD_PERSON_RIGHT_HAND;};}@Overrideprotected void renderItemForBone(AzRendererPipelineContext<UUID, ExampleEntity> context, AzBone bone, ItemStack itemStack, ExampleEntity animatable) {context.poseStack().mulPose(Axis.XP.rotationDegrees(270));context.poseStack().translate(0.0D, 0.1D, -0.1D);super.renderItemForBone(context, bone, itemStack, animatable);}}).build(),context);}}
Troubleshooting
-
Items/Blocks Not Rendering:
- Ensure the bone name in your
itemStackForBone/blockStateForBonelogic matches the name declared in the model file.
- Ensure the bone name in your
-
Incorrect Positioning:
- Use the
renderItemForBoneorrenderBlockForBonemethods to fine-tune the rotation, translation, and scaling.
- Use the
-
Performance Issues:
- Verify that your item stack/block state providers aren’t performing excessive calculations. Cache results when possible.