From aeaa518d417eed77aef0230a2802dfb4c9c39069 Mon Sep 17 00:00:00 2001 From: BlayTheNinth <1933180+BlayTheNinth@users.noreply.github.com> Date: Mon, 1 Jan 2024 13:02:49 +0100 Subject: [PATCH] feat: Add lil human in printer --- .../block/PrinterBlock.java | 11 +++ .../block/entity/PrinterBlockEntity.java | 9 +++ .../client/render/BlenderRenderer.java | 4 +- .../client/render/PrinterRenderer.java | 73 +++++++++++++++-- .../client/render/RenderUtils.java | 30 ------- .../client/render/TinyHumanModel.java | 80 +++++++++++++++++++ 6 files changed, 171 insertions(+), 36 deletions(-) delete mode 100644 shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/RenderUtils.java create mode 100644 shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/TinyHumanModel.java diff --git a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/block/PrinterBlock.java b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/block/PrinterBlock.java index 2da1efa..0d02a6a 100644 --- a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/block/PrinterBlock.java +++ b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/block/PrinterBlock.java @@ -130,4 +130,15 @@ public float getShadeBrightness(BlockState blockState, BlockGetter blockGetter, public boolean propagatesSkylightDown(BlockState blockState, BlockGetter blockGetter, BlockPos blockPos) { return true; } + + @Override + public boolean useShapeForLightOcclusion(BlockState $$0) { + return false; + } + + @Override + public int getLightBlock(BlockState $$0, BlockGetter $$1, BlockPos $$2) { + return 1; + } + } diff --git a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/block/entity/PrinterBlockEntity.java b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/block/entity/PrinterBlockEntity.java index 1e03a47..82549f4 100644 --- a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/block/entity/PrinterBlockEntity.java +++ b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/block/entity/PrinterBlockEntity.java @@ -106,6 +106,8 @@ public void setEnergy(int energy) { private PrinterRecipe currentRecipe; private ItemStack currentResultItem = ItemStack.EMPTY; + private float animationTime; + protected final ContainerData dataAccess = new ContainerData() { public int get(int i) { return switch (i) { @@ -293,4 +295,11 @@ public void setChanged() { super.setChanged(); dirtyForSync = true; } + + public float animate(float partialTicks) { + if (energyCostPerTick > 0 || true) { + animationTime += partialTicks; + } + return animationTime; + } } diff --git a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/BlenderRenderer.java b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/BlenderRenderer.java index f4f53a0..d421965 100644 --- a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/BlenderRenderer.java +++ b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/BlenderRenderer.java @@ -10,6 +10,7 @@ import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemDisplayContext; import org.joml.AxisAngle4f; import org.joml.Quaternionf; @@ -48,6 +49,7 @@ public void render(BlenderBlockEntity blockEntity, float partialTicks, PoseStack final var angleSpeed = 0.25f; final var cosah = Math.cos(animationTime * speedH) * offsetH; final var sinah = Math.sin(animationTime * speedH) * offsetH; + final var itemRenderer = Minecraft.getInstance().getItemRenderer(); for (int i = 0; i < inputContainer.getContainerSize(); i++) { poseStack.pushPose(); final var alt = i % 2 == 0; @@ -63,7 +65,7 @@ public void render(BlenderBlockEntity blockEntity, float partialTicks, PoseStack final var itemStack = inputContainer.getItem(i); if (!itemStack.isEmpty()) { - RenderUtils.renderItem(itemStack, combinedLight, poseStack, buffer, blockEntity.getLevel()); + itemRenderer.renderStatic(itemStack, ItemDisplayContext.FIXED, combinedLight, combinedOverlayIn, poseStack, buffer, level, 0); } poseStack.popPose(); } diff --git a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/PrinterRenderer.java b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/PrinterRenderer.java index dc6e38e..083502c 100644 --- a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/PrinterRenderer.java +++ b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/PrinterRenderer.java @@ -1,30 +1,45 @@ package net.blay09.mods.forbiddensmoothies.client.render; +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.minecraft.MinecraftProfileTexture; import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.vertex.PoseStack; import net.blay09.mods.forbiddensmoothies.block.CustomBlockStateProperties; import net.blay09.mods.forbiddensmoothies.block.entity.PrinterBlockEntity; import net.blay09.mods.forbiddensmoothies.client.ModModels; import net.minecraft.client.Minecraft; +import net.minecraft.client.model.geom.ModelLayers; import net.minecraft.client.renderer.LightTexture; import net.minecraft.client.renderer.MultiBufferSource; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.blockentity.BlockEntityRenderer; import net.minecraft.client.renderer.blockentity.BlockEntityRendererProvider; +import net.minecraft.client.resources.DefaultPlayerSkin; +import net.minecraft.resources.ResourceLocation; import net.minecraft.util.RandomSource; import net.minecraft.world.item.ItemDisplayContext; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import org.jetbrains.annotations.Nullable; import org.joml.AxisAngle4f; import org.joml.Quaternionf; +import java.util.Optional; + public class PrinterRenderer implements BlockEntityRenderer { private static final RandomSource random = RandomSource.create(); + private final TinyHumanModel tinyHumanModel; + private final TinyHumanModel tinyHumanModelSlim; + public PrinterRenderer(BlockEntityRendererProvider.Context context) { + tinyHumanModel = new TinyHumanModel(context.bakeLayer(ModelLayers.PLAYER), false); + tinyHumanModelSlim = new TinyHumanModel(context.bakeLayer(ModelLayers.PLAYER_SLIM), true); } @Override - public void render(PrinterBlockEntity blockEntity, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int combinedLight, int combinedOverlayIn) { + public void render(PrinterBlockEntity blockEntity, float partialTicks, PoseStack poseStack, MultiBufferSource buffer, int combinedLight, int combinedOverlay) { final var level = blockEntity.getLevel(); if (level == null) { return; @@ -37,7 +52,7 @@ public void render(PrinterBlockEntity blockEntity, float partialTicks, PoseStack final var dispatcher = Minecraft.getInstance().getBlockRenderer(); poseStack.pushPose(); - poseStack.translate(-0.05f, 0f, 0.1f); + poseStack.translate(-0.05f, 0.01f, 0.1f); dispatcher.getModelRenderer() .tesselateBlock(level, ModModels.printerEasel.get(), @@ -55,14 +70,62 @@ public void render(PrinterBlockEntity blockEntity, float partialTicks, PoseStack poseStack.pushPose(); poseStack.translate(0.5f, 0f, 0.5f); final var itemScale = 0.3f; - poseStack.translate(-0.08f, 0.425f, 0.115f); + poseStack.translate(-0.08f, 0.43f, 0.115f); poseStack.mulPose(new Quaternionf(new AxisAngle4f((float) Math.toRadians(22.5f), 1f, 0f, 0f))); poseStack.scale(itemScale, itemScale, 0.1f); final var itemRenderer = Minecraft.getInstance().getItemRenderer(); - final var model = itemRenderer.getModel(itemStack, level, null, combinedLight); + final var model = itemRenderer.getModel(itemStack, level, null, 0); RenderSystem.enableBlend(); - itemRenderer.render(itemStack, ItemDisplayContext.FIXED, false, poseStack, buffer, LightTexture.FULL_BLOCK, combinedOverlayIn, model); + itemRenderer.render(itemStack, ItemDisplayContext.FIXED, false, poseStack, buffer, LightTexture.FULL_BLOCK, combinedOverlay, model); poseStack.popPose(); + + final var animationTime = blockEntity.animate(partialTicks); + + poseStack.pushPose(); + poseStack.translate(0.5f, 0f, 0.5f); + poseStack.mulPose(new Quaternionf(new AxisAngle4f((float) Math.toRadians(180), 1f, 0f, 0f))); + poseStack.mulPose(new Quaternionf(new AxisAngle4f((float) Math.toRadians(120), 0f, 1f, 0f))); + poseStack.translate(-0.15f, -0.95f, 0.1f); + final var humanScale = 0.55f; + poseStack.scale(humanScale, humanScale, humanScale); + final GameProfile gameProfile = null; // TODO + final var profileTexture = getPlayerSkin(gameProfile).orElse(null); + final var playerModel = getPlayerModel(profileTexture); + final var skinTexture = getPlayerSkinTexture(profileTexture); + playerModel.animate(animationTime); + playerModel.renderToBuffer(poseStack, buffer.getBuffer(RenderType.entitySolid(skinTexture)), LightTexture.FULL_BLOCK, combinedOverlay, 1f, 1f, 1f, 1f); + poseStack.popPose(); + + playerModel.renderItemInHand(poseStack, buffer, LightTexture.FULL_BLOCK, combinedOverlay, level); } + private Optional getPlayerSkin(@Nullable GameProfile gameProfile) { + if (gameProfile != null) { + final var skinInformation = Minecraft.getInstance().getSkinManager().getInsecureSkinInformation(gameProfile); + return Optional.ofNullable(skinInformation.get(MinecraftProfileTexture.Type.SKIN)); + } else { + return Optional.empty(); + } + } + + private TinyHumanModel getPlayerModel(@Nullable MinecraftProfileTexture profileTexture) { + if (profileTexture != null) { + final var model = profileTexture.getMetadata("model"); + if ("slim".equals(model)) { + return tinyHumanModelSlim; + } else { + return tinyHumanModel; + } + } + + return tinyHumanModelSlim; + } + + private ResourceLocation getPlayerSkinTexture(@Nullable MinecraftProfileTexture profileTexture) { + if (profileTexture != null) { + return Minecraft.getInstance().getSkinManager().registerTexture(profileTexture, MinecraftProfileTexture.Type.SKIN); + } else { + return DefaultPlayerSkin.getDefaultSkin(); + } + } } diff --git a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/RenderUtils.java b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/RenderUtils.java deleted file mode 100644 index 5611552..0000000 --- a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/RenderUtils.java +++ /dev/null @@ -1,30 +0,0 @@ -package net.blay09.mods.forbiddensmoothies.client.render; - -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.math.Axis; -import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; - -public class RenderUtils { - - public static void applyBlockAngle(PoseStack poseStack, BlockState state) { - applyBlockAngle(poseStack, state, 180f); - } - - public static void applyBlockAngle(PoseStack poseStack, BlockState state, float angleOffset) { - float angle = state.getValue(BlockStateProperties.FACING).toYRot(); - poseStack.translate(0.5, 0, 0.5); - poseStack.mulPose(Axis.YP.rotationDegrees(angleOffset - angle)); - } - - public static void renderItem(ItemStack itemStack, int combinedLight, PoseStack poseStack, MultiBufferSource buffer, Level level) { - Minecraft.getInstance().getItemRenderer().renderStatic(itemStack, ItemDisplayContext.FIXED.FIXED, combinedLight, OverlayTexture.NO_OVERLAY, poseStack, buffer, level, 0); - } - -} diff --git a/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/TinyHumanModel.java b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/TinyHumanModel.java new file mode 100644 index 0000000..ba0053b --- /dev/null +++ b/shared/src/main/java/net/blay09/mods/forbiddensmoothies/client/render/TinyHumanModel.java @@ -0,0 +1,80 @@ +package net.blay09.mods.forbiddensmoothies.client.render; + +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; +import net.minecraft.client.Minecraft; +import net.minecraft.client.model.PlayerModel; +import net.minecraft.client.model.geom.ModelPart; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.world.entity.HumanoidArm; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.level.Level; + +public class TinyHumanModel extends PlayerModel { + + public TinyHumanModel(ModelPart modelPart, boolean slim) { + super(modelPart, slim); + } + + public void animate(float animationTime) { + rightArm.xRot = 0.1f; + leftLeg.xRot = -0.1f; + leftArm.yRot = 0.1f; + leftArm.zRot = (float) (-Math.sin(animationTime / 20f) - Math.toRadians(50f)); + head.zRot =(float) (-Math.sin(animationTime / 40f)) * 0.1f; + head.xRot =(float) (-Math.sin(animationTime / 60f)) * 0.05f; + head.yRot =(float) (-Math.sin(animationTime / 30f)) * 0.05f; + } + + @Override + public void renderToBuffer(PoseStack poseStack, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) { + float scale = 0.0625f; + + poseStack.pushPose(); + + poseStack.scale(0.75F, 0.75F, 0.75F); + poseStack.translate(0.0F, 16.0F * scale, 0.0F); + this.head.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha); + poseStack.popPose(); + poseStack.pushPose(); + poseStack.scale(0.5F, 0.5F, 0.5F); + poseStack.translate(0.0F, 24.0F * scale, 0.0F); + this.body.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha); + this.rightArm.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha); + this.leftArm.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha); + this.rightLeg.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha); + this.leftLeg.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha); + //this.hat.render(poseStack, vertexConsumer, packedLight, packedOverlay, red, green, blue, alpha); + + poseStack.popPose(); + } + + public void renderItemInHand(PoseStack poseStack, MultiBufferSource buffer, int combinedLight, int combinedOverlay, Level level) { + //final var itemRenderer = Minecraft.getInstance().getItemRenderer(); + //final var brushItem = new ItemStack(Items.BRUSH); + //poseStack.pushPose(); + //rightArm.translateAndRotate(poseStack); + //final var itemScale = 0.2f; + //poseStack.translate(0.25f, 0.3f, 0f); + //poseStack.scale(itemScale, itemScale, itemScale); + //itemRenderer.renderStatic(brushItem, ItemDisplayContext.FIXED, combinedLight, combinedOverlay, poseStack, buffer, level, 0); + //poseStack.popPose(); + + final var itemRenderer = Minecraft.getInstance().getItemRenderer(); + final var itemStack = new ItemStack(Items.BRUSH); + poseStack.pushPose(); + final var humanScale= 0.55f; + //poseStack.scale(humanScale, humanScale, humanScale); + translateToHand(HumanoidArm.LEFT, poseStack); + //poseStack.mulPose(Axis.XP.rotationDegrees(-90f)); + poseStack.mulPose(Axis.YP.rotationDegrees(120f)); + poseStack.translate( -1f / 16f, 0.125f, -0.625f); + final var itemScale = 1f; + poseStack.scale(itemScale, itemScale, itemScale); + //itemRenderer.renderStatic(itemStack, ItemDisplayContext.THIRD_PERSON_LEFT_HAND, combinedLight, combinedOverlay, poseStack, buffer, level, 0); + poseStack.popPose(); + } +}