Skip to content

Instantly share code, notes, and snippets.

@HexBugOrion
Created July 11, 2026 17:57
Show Gist options
  • Select an option

  • Save HexBugOrion/a1df750f8bbc4b8ee319fa15bbe2d5f2 to your computer and use it in GitHub Desktop.

Select an option

Save HexBugOrion/a1df750f8bbc4b8ee319fa15bbe2d5f2 to your computer and use it in GitHub Desktop.
package net.tws.nowhere.render;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Axis;
import it.unimi.dsi.fastutil.ints.Int2IntFunction;
import net.minecraft.client.model.geom.ModelLayers;
import net.minecraft.client.model.geom.ModelPart;
import net.minecraft.client.model.geom.PartPose;
import net.minecraft.client.model.geom.builders.CubeListBuilder;
import net.minecraft.client.model.geom.builders.LayerDefinition;
import net.minecraft.client.model.geom.builders.MeshDefinition;
import net.minecraft.client.model.geom.builders.PartDefinition;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.Sheets;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider;
import net.minecraft.client.renderer.blockentity.BrightnessCombiner;
import net.minecraft.client.resources.model.Material;
import net.minecraft.core.Direction;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.BedBlock;
import net.minecraft.world.level.block.ChestBlock;
import net.minecraft.world.level.block.DoubleBlockCombiner;
import net.minecraft.world.level.block.entity.BedBlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.properties.BedPart;
public class MeanBedRenderer implements BlockEntityRenderer<BedBlockEntity> {
private final ModelPart headRoot;
private final ModelPart footRoot;
public MeanBedRenderer(BlockEntityRendererProvider.Context context) {
this.headRoot = context.bakeLayer(ModelLayers.BED_HEAD);
this.footRoot = context.bakeLayer(ModelLayers.BED_FOOT);
}
public static LayerDefinition createHeadLayer() {
MeshDefinition meshdefinition = new MeshDefinition();
PartDefinition partdefinition = meshdefinition.getRoot();
partdefinition.addOrReplaceChild("main", CubeListBuilder.create().texOffs(0, 0).addBox(0.0F, 0.0F, 0.0F, 16.0F, 16.0F, 6.0F), PartPose.ZERO);
partdefinition.addOrReplaceChild("left_leg", CubeListBuilder.create().texOffs(50, 6).addBox(0.0F, 6.0F, 0.0F, 3.0F, 3.0F, 3.0F), PartPose.rotation(((float)Math.PI / 2F), 0.0F, ((float)Math.PI / 2F)));
partdefinition.addOrReplaceChild("right_leg", CubeListBuilder.create().texOffs(50, 18).addBox(-16.0F, 6.0F, 0.0F, 3.0F, 3.0F, 3.0F), PartPose.rotation(((float)Math.PI / 2F), 0.0F, (float)Math.PI));
return LayerDefinition.create(meshdefinition, 64, 64);
}
public static LayerDefinition createFootLayer() {
MeshDefinition meshdefinition = new MeshDefinition();
PartDefinition partdefinition = meshdefinition.getRoot();
partdefinition.addOrReplaceChild("main", CubeListBuilder.create().texOffs(0, 22).addBox(0.0F, 0.0F, 0.0F, 16.0F, 16.0F, 6.0F), PartPose.ZERO);
partdefinition.addOrReplaceChild("left_leg", CubeListBuilder.create().texOffs(50, 0).addBox(0.0F, 6.0F, -16.0F, 3.0F, 3.0F, 3.0F), PartPose.rotation(((float)Math.PI / 2F), 0.0F, 0.0F));
partdefinition.addOrReplaceChild("right_leg", CubeListBuilder.create().texOffs(50, 12).addBox(-16.0F, 6.0F, -16.0F, 3.0F, 3.0F, 3.0F), PartPose.rotation(((float)Math.PI / 2F), 0.0F, ((float)Math.PI * 1.5F)));
return LayerDefinition.create(meshdefinition, 64, 64);
}
public void render(BedBlockEntity blockEntity, float partialTick, PoseStack poseStack, MultiBufferSource bufferSource, int packedLight, int packedOverlay) {
Material material = NWSheets.BED_TEXTURES[blockEntity.getColor().getId()];
Level level = blockEntity.getLevel();
if (level != null) {
BlockState blockstate = blockEntity.getBlockState();
DoubleBlockCombiner.NeighborCombineResult<? extends BedBlockEntity> neighborcombineresult = DoubleBlockCombiner.combineWithNeigbour(BlockEntityType.BED, BedBlock::getBlockType, BedBlock::getConnectedDirection, ChestBlock.FACING, blockstate, level, blockEntity.getBlockPos(), (p_112202_, p_112203_) -> false);
int i = ((Int2IntFunction)neighborcombineresult.apply(new BrightnessCombiner())).get(packedLight);
this.renderPiece(poseStack, bufferSource, blockstate.getValue(BedBlock.PART) == BedPart.HEAD ? this.headRoot : this.footRoot, (Direction)blockstate.getValue(BedBlock.FACING), material, i, packedOverlay, false);
} else {
this.renderPiece(poseStack, bufferSource, this.headRoot, Direction.SOUTH, material, packedLight, packedOverlay, false);
this.renderPiece(poseStack, bufferSource, this.footRoot, Direction.SOUTH, material, packedLight, packedOverlay, true);
}
}
private void renderPiece(PoseStack poseStack, MultiBufferSource bufferSource, ModelPart modelPart, Direction direction, Material material, int packedLight, int packedOverlay, boolean foot) {
poseStack.pushPose();
poseStack.translate(0.0F, 0.5625F, foot ? -1.0F : 0.0F);
poseStack.mulPose(Axis.XP.rotationDegrees(90.0F));
poseStack.translate(0.5F, 0.5F, 0.5F);
poseStack.mulPose(Axis.ZP.rotationDegrees(180.0F + direction.toYRot()));
poseStack.translate(-0.5F, -0.5F, -0.5F);
VertexConsumer vertexconsumer = material.buffer(bufferSource, RenderType::entitySolid);
modelPart.render(poseStack, vertexconsumer, packedLight, packedOverlay);
poseStack.popPose();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment