From 4b27c921f8fe27d6f7a774c0b9e933d74b000a1b Mon Sep 17 00:00:00 2001 From: UnlikePaladin <36827970+UnlikePaladin@users.noreply.github.com> Date: Sun, 1 Oct 2023 19:44:29 -0600 Subject: [PATCH] Added Elytra Pivot --- .../layers/elytra/ElytraLayerMixin.java | 66 ++++++++++++++++--- .../org/figuramc/figura/model/ParentType.java | 1 + .../figuramc/figura/wizards/AvatarWizard.java | 1 + 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/common/src/main/java/org/figuramc/figura/mixin/render/layers/elytra/ElytraLayerMixin.java b/common/src/main/java/org/figuramc/figura/mixin/render/layers/elytra/ElytraLayerMixin.java index fa706be1c..0e165c787 100644 --- a/common/src/main/java/org/figuramc/figura/mixin/render/layers/elytra/ElytraLayerMixin.java +++ b/common/src/main/java/org/figuramc/figura/mixin/render/layers/elytra/ElytraLayerMixin.java @@ -1,16 +1,28 @@ package org.figuramc.figura.mixin.render.layers.elytra; import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import com.mojang.math.Axis; import net.minecraft.client.model.ElytraModel; import net.minecraft.client.model.EntityModel; +import net.minecraft.client.player.AbstractClientPlayer; import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.renderer.entity.RenderLayerParent; import net.minecraft.client.renderer.entity.layers.ElytraLayer; import net.minecraft.client.renderer.entity.layers.RenderLayer; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.EquipmentSlot; import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.PlayerModelPart; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; import org.figuramc.figura.avatar.Avatar; import org.figuramc.figura.avatar.AvatarManager; import org.figuramc.figura.lua.api.vanilla_model.VanillaPart; +import org.figuramc.figura.model.ParentType; import org.figuramc.figura.permissions.Permissions; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; @@ -28,33 +40,69 @@ public ElytraLayerMixin(RenderLayerParent context) { } @Shadow @Final private ElytraModel elytraModel; + @Shadow @Final private static ResourceLocation WINGS_LOCATION; @Unique private VanillaPart vanillaPart; + @Unique + private Avatar figura$avatar; + + @Unique + private boolean renderedPivot; + + @Inject(at = @At(value = "HEAD"), method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ILnet/minecraft/world/entity/LivingEntity;FFFFFF)V") + public void renderElytra(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, T livingEntity, float f, float g, float h, float j, float k, float l, CallbackInfo ci) { + figura$avatar = AvatarManager.getAvatar(livingEntity); + + if (figura$avatar == null) return; + + ItemStack itemStack = livingEntity.getItemBySlot(EquipmentSlot.CHEST); + if (!itemStack.is(Items.ELYTRA)) { + return; + } + + // Try to render the pivot part + renderedPivot = figura$avatar.pivotPartRender(ParentType.ElytraPivot, stack -> { + stack.pushPose(); + stack.scale(16, 16, 16); + stack.mulPose(Axis.XP.rotationDegrees(180f)); + stack.mulPose(Axis.YP.rotationDegrees(180f)); + stack.translate(0.0f, 0.0f, 0.125f); + this.elytraModel.setupAnim(livingEntity, f, g, h, i, j); + ResourceLocation resourceLocation = livingEntity instanceof AbstractClientPlayer abstractClientPlayer ? (abstractClientPlayer.isElytraLoaded() && abstractClientPlayer.getElytraTextureLocation() != null ? abstractClientPlayer.getElytraTextureLocation() : (abstractClientPlayer.isCapeLoaded() && abstractClientPlayer.getCloakTextureLocation() != null && abstractClientPlayer.isModelPartShown(PlayerModelPart.CAPE) ? abstractClientPlayer.getCloakTextureLocation() : WINGS_LOCATION)) : WINGS_LOCATION; + VertexConsumer vertexConsumer = ItemRenderer.getArmorFoilBuffer(multiBufferSource, RenderType.armorCutoutNoCull(resourceLocation), false, itemStack.hasFoil()); + this.elytraModel.renderToBuffer(stack, vertexConsumer, i, OverlayTexture.NO_OVERLAY, 1.0f, 1.0f, 1.0f, 1.0f); + stack.popPose(); + }); + } - @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/model/ElytraModel;setupAnim(Lnet/minecraft/world/entity/LivingEntity;FFFFF)V", shift = At.Shift.AFTER), method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ILnet/minecraft/world/entity/LivingEntity;FFFFFF)V") + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/model/ElytraModel;setupAnim(Lnet/minecraft/world/entity/LivingEntity;FFFFF)V", shift = At.Shift.AFTER), method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ILnet/minecraft/world/entity/LivingEntity;FFFFFF)V", cancellable = true) public void onRender(PoseStack poseStack, MultiBufferSource multiBufferSource, int light, T livingEntity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch, CallbackInfo ci) { vanillaPart = null; - Avatar avatar = AvatarManager.getAvatar(livingEntity); - if (avatar == null) + if (figura$avatar == null) return; - if (avatar.luaRuntime != null) { - VanillaPart part = avatar.luaRuntime.vanilla_model.ELYTRA; + if (figura$avatar.luaRuntime != null) { + VanillaPart part = figura$avatar.luaRuntime.vanilla_model.ELYTRA; part.save(elytraModel); - if (avatar.permissions.get(Permissions.VANILLA_MODEL_EDIT) == 1) { + if (figura$avatar.permissions.get(Permissions.VANILLA_MODEL_EDIT) == 1) { vanillaPart = part; vanillaPart.preTransform(elytraModel); } } - avatar.elytraRender(livingEntity, multiBufferSource, poseStack, light, tickDelta, elytraModel); + figura$avatar.elytraRender(livingEntity, multiBufferSource, poseStack, light, tickDelta, elytraModel); if (vanillaPart != null) vanillaPart.posTransform(elytraModel); + + if (renderedPivot) { + poseStack.popPose(); + ci.cancel(); + } } - @Inject(at = @At("RETURN"), method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ILnet/minecraft/world/entity/LivingEntity;FFFFFF)V") - public void postRender(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, T livingEntity, float f, float g, float h, float j, float k, float l, CallbackInfo ci) { + @Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/model/ElytraModel;renderToBuffer(Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;IIFFFF)V"), method = "render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource;ILnet/minecraft/world/entity/LivingEntity;FFFFFF)V") + public void cancelVanillaPart(PoseStack poseStack, MultiBufferSource multiBufferSource, int i, T livingEntity, float f, float g, float h, float j, float k, float l, CallbackInfo ci) { if (vanillaPart != null) vanillaPart.restore(elytraModel); } diff --git a/common/src/main/java/org/figuramc/figura/model/ParentType.java b/common/src/main/java/org/figuramc/figura/model/ParentType.java index f1f832edd..c78af1bca 100644 --- a/common/src/main/java/org/figuramc/figura/model/ParentType.java +++ b/common/src/main/java/org/figuramc/figura/model/ParentType.java @@ -45,6 +45,7 @@ public enum ParentType { HelmetItemPivot(false, true,"HELMET_ITEM_PIVOT"), HelmetPivot(false, true, "HELMET_PIVOT", "HelmetPivot"), ChestplatePivot(false, true, "CHESTPLATE_PIVOT", "ChestplatePivot"), + ElytraPivot(false, true, "ELYTRA_PIVOT", "ElytraPivot"), LeftShoulderPivot(false, true, "LEFT_SHOULDER_PIVOT", "LeftShoulderPivot"), RightShoulderPivot(false, true, "RIGHT_SHOULDER_PIVOT", "RightShoulderPivot"), LeggingsPivot(false, true, "LEGGINGS_PIVOT", "LeggingsPivot"), diff --git a/common/src/main/java/org/figuramc/figura/wizards/AvatarWizard.java b/common/src/main/java/org/figuramc/figura/wizards/AvatarWizard.java index 97b00794a..3faf5288f 100644 --- a/common/src/main/java/org/figuramc/figura/wizards/AvatarWizard.java +++ b/common/src/main/java/org/figuramc/figura/wizards/AvatarWizard.java @@ -314,6 +314,7 @@ else if (hasCapeOrElytra) if (hasArmor) { model.addGroup(HelmetPivot, FiguraVec3.of(0, 24, 0), head); model.addGroup(ChestplatePivot, FiguraVec3.of(0, 24, 0), body); + model.addGroup(ElytraPivot, FiguraVec3.of(0, 24, 0), body); model.addGroup(LeftShoulderPivot, FiguraVec3.of(-6, 24, 0), leftArm); model.addGroup(RightShoulderPivot, FiguraVec3.of(6, 24, 0), rightArm); model.addGroup(LeggingsPivot, FiguraVec3.of(0, 12, 0), body);