Skip to content

Commit

Permalink
- Removed the Elytra Pivot and separated it into LeftElytraPivot and …
Browse files Browse the repository at this point in the history
…RightElytraPivot with aliases RightWingPivot and RightWingPivot

- Added extra aliases for ChestplatePivot, now is ChestplateBodyPivot and for LeggingsPivot, now is also BeltPivot

- Fixed a bug where hiding the vanilla model armpr part wouldn't hide the corresponding armor part if it had a pivot
  • Loading branch information
UnlikePaladin committed Jan 31, 2024
1 parent 188f8c1 commit a125d4b
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 33 deletions.
Expand Up @@ -8,8 +8,10 @@
import net.minecraft.world.item.Item;
import org.figuramc.figura.avatar.Avatar;
import org.figuramc.figura.ducks.GeckolibGeoArmorAccessor;
import org.figuramc.figura.lua.api.vanilla_model.VanillaPart;
import org.figuramc.figura.model.ParentType;
import org.figuramc.figura.permissions.Permissions;
import org.figuramc.figura.utils.RenderUtils;
import org.spongepowered.asm.mixin.*;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
Expand Down Expand Up @@ -103,12 +105,17 @@ default void actuallyRender(PoseStack poseStack, T animatable, BakedGeoModel mod
}
}

// Returns the true if the pivot failed to render to match HumanoidArmorLayerMixin
// Returns true if the pivot failed to render, false if it was successful to match HumanoidArmorLayerMixin
@Unique
default boolean figura$renderPivot(GeoArmorRenderer armorRenderer, Avatar avatar, ParentType parentType, GeoAnimatable geoAnimatable, GeoBone geoBone, RenderType renderType, MultiBufferSource multiBufferSource, VertexConsumer vertexConsumer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
if (geoBone == null)
return true;

// Returns successfully but skips rendering if the part is hidden
VanillaPart part = RenderUtils.pivotToPart(avatar, parentType);
if (avatar.permissions.get(Permissions.VANILLA_MODEL_EDIT) == 1 && part != null && !part.checkVisible())
return false;

return !avatar.pivotPartRender(parentType, stack -> {
geoBone.setRotX(0);
geoBone.setRotY(0);
Expand Down
Expand Up @@ -109,8 +109,6 @@ public void postRenderArmorPiece(PoseStack poseStack, MultiBufferSource multiBuf
@Unique
private void figura$tryRenderArmorPart(EquipmentSlot slot, FiguraArmorPartRenderer<T, M, A> renderer, PoseStack vanillaPoseStack, T entity, MultiBufferSource vertexConsumers, int light, ParentType... parentTypes) {
if (slot == null) return; // ?
VanillaPart part = RenderUtils.partFromSlot(figura$avatar, slot);
if (figura$avatar.permissions.get(Permissions.VANILLA_MODEL_EDIT) == 1 && part != null && !part.checkVisible()) return;

ItemStack itemStack = entity.getItemBySlot(slot);

Expand All @@ -134,12 +132,18 @@ public void postRenderArmorPiece(PoseStack poseStack, MultiBufferSource multiBuf
armorModel.rightArm.z = 0.0f;

boolean allFailed = true;
VanillaPart mainPart = RenderUtils.partFromSlot(figura$avatar, slot);
if (figura$avatar.permissions.get(Permissions.VANILLA_MODEL_EDIT) == 1 && mainPart != null && !mainPart.checkVisible()) return;

// Don't render armor if GeckoLib is already doing the rendering
if (!GeckoLibCompat.armorHasCustomModel(itemStack)) {
// Go through each parent type needed to render the current piece of armor
for (ParentType parentType : parentTypes) {
// Try to render the pivot part
// Skip the part if it's hidden
VanillaPart part = RenderUtils.pivotToPart(figura$avatar, parentType);
if (figura$avatar.permissions.get(Permissions.VANILLA_MODEL_EDIT) == 1 && part != null && !part.checkVisible()) continue;

// Try to render the pivot part
boolean renderedPivot = figura$avatar.pivotPartRender(parentType, stack -> {
stack.pushPose();
figura$prepareArmorRender(stack);
Expand Down
Expand Up @@ -25,6 +25,7 @@
import org.figuramc.figura.model.ParentType;
import org.figuramc.figura.permissions.Permissions;
import org.figuramc.figura.utils.PlatformUtils;
import org.figuramc.figura.utils.RenderUtils;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
Expand Down Expand Up @@ -81,38 +82,61 @@ public void onRender(PoseStack poseStack, MultiBufferSource multiBufferSource, i
public void cancelVanillaPart(PoseStack poseStack, MultiBufferSource multiBufferSource, int light, T livingEntity, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch, CallbackInfo ci) {
if (vanillaPart != null)
vanillaPart.restore(elytraModel);
renderedPivot = true;

renderElytraPivot(poseStack, multiBufferSource, light, livingEntity, limbAngle, limbDistance, tickDelta, animationProgress);
if (renderedPivot) {
poseStack.popPose();
ci.cancel();
}
}

public void renderElytraPivot(PoseStack poseStack, MultiBufferSource multiBufferSource, int light, T livingEntity, float limbAngle, float limbDistance, float tickDelta, float animationProgress) {

ItemStack itemStack = livingEntity.getItemBySlot(EquipmentSlot.CHEST);
if (!itemStack.is(Items.ELYTRA) && !PlatformUtils.isModLoaded("origins")) {
return;
}
if (figura$avatar != null && figura$avatar.luaRuntime != null && figura$avatar.permissions.get(Permissions.VANILLA_MODEL_EDIT) == 1 && figura$avatar.luaRuntime.vanilla_model.ELYTRA.checkVisible()) {
// 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, limbAngle, limbDistance, tickDelta, light, animationProgress);
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, light, OverlayTexture.NO_OVERLAY, 1.0f, 1.0f, 1.0f, 1.0f);
stack.popPose();
});
} else if (figura$avatar != null && figura$avatar.luaRuntime != null && figura$avatar.permissions.get(Permissions.VANILLA_MODEL_EDIT) == 1 && !figura$avatar.luaRuntime.vanilla_model.ELYTRA.checkVisible()){
renderedPivot = true;
poseStack.popPose();
ci.cancel();
return;
} else {
renderedPivot = false;
}
this.elytraModel.setupAnim(livingEntity, limbAngle, limbDistance, tickDelta, light, animationProgress);

if (renderedPivot) {
poseStack.popPose();
ci.cancel();
}
VanillaPart part = RenderUtils.pivotToPart(figura$avatar, ParentType.LeftElytraPivot);

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());

if (part != null && part.checkVisible()) {
boolean leftWing = figura$avatar.pivotPartRender(ParentType.LeftElytraPivot, 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);

((ElytraModelAccessor)this.elytraModel).getLeftWing().render(stack, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0f, 1.0f, 1.0f, 1.0f);
stack.popPose();
});
if (!leftWing) {
((ElytraModelAccessor)this.elytraModel).getLeftWing().render(poseStack, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0f, 1.0f, 1.0f, 1.0f);
}
}
part = RenderUtils.pivotToPart(figura$avatar, ParentType.RightElytraPivot);
if (part != null && part.checkVisible()) {
boolean rightWing = figura$avatar.pivotPartRender(ParentType.RightElytraPivot, 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);

((ElytraModelAccessor)this.elytraModel).getRightWing().render(stack, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0f, 1.0f, 1.0f, 1.0f);
stack.popPose();
});
if (!rightWing) {
((ElytraModelAccessor)this.elytraModel).getRightWing().render(poseStack, vertexConsumer, light, OverlayTexture.NO_OVERLAY, 1.0f, 1.0f, 1.0f, 1.0f);
}
}
} else renderedPivot = figura$avatar != null && figura$avatar.luaRuntime != null && figura$avatar.permissions.get(Permissions.VANILLA_MODEL_EDIT) == 1 && !figura$avatar.luaRuntime.vanilla_model.ELYTRA.checkVisible();
}
}
Expand Up @@ -45,11 +45,12 @@ public enum ParentType {
// Armor
HelmetItemPivot(false, true,"HELMET_ITEM_PIVOT"),
HelmetPivot(false, true, "HELMET_PIVOT", "HelmetPivot"),
ChestplatePivot(false, true, "CHESTPLATE_PIVOT", "ChestplatePivot"),
ElytraPivot(false, true, "ELYTRA_PIVOT", "ElytraPivot"),
ChestplatePivot(false, true, "CHESTPLATE_PIVOT", "ChestplatePivot", "ChestplateBodyPivot", "CHESTPLATE_BODY_PIVOT"),
LeftElytraPivot(false, true, "LEFT_ELYTRA_PIVOT", "LeftElytraPivot", "LeftWingPivot", "LEFT_WING_PIVOT"),
RightElytraPivot(false, true, "RIGHT_ELYTRA_PIVOT", "RightElytraPivot", "RightWingPivot", "RIGHT_WING_PIVOT"),
LeftShoulderPivot(false, true, "LEFT_SHOULDER_PIVOT", "LeftShoulderPivot"),
RightShoulderPivot(false, true, "RIGHT_SHOULDER_PIVOT", "RightShoulderPivot"),
LeggingsPivot(false, true, "LEGGINGS_PIVOT", "LeggingsPivot"),
LeggingsPivot(false, true, "LEGGINGS_PIVOT", "LeggingsPivot", "BeltPivot", "BELT_PIVOT"),
LeftBootPivot(false, true, "LEFT_BOOT_PIVOT", "LeftBootPivot"),
RightBootPivot(false, true, "RIGHT_BOOT_PIVOT", "RightBootPivot");

Expand Down
22 changes: 21 additions & 1 deletion common/src/main/java/org/figuramc/figura/utils/RenderUtils.java
Expand Up @@ -64,12 +64,32 @@ public static VanillaPart partFromSlot(Avatar avatar, EquipmentSlot equipmentSlo
};
}

public static VanillaPart pivotToPart(Avatar avatar, ParentType type) {
if (!RenderUtils.vanillaModelAndScript(avatar))
return null;

return switch (type) {
case HelmetPivot -> avatar.luaRuntime.vanilla_model.HELMET;
case ChestplatePivot -> avatar.luaRuntime.vanilla_model.CHESTPLATE;
case LeftShoulderPivot -> avatar.luaRuntime.vanilla_model.CHESTPLATE_LEFT_ARM;
case RightShoulderPivot -> avatar.luaRuntime.vanilla_model.CHESTPLATE_RIGHT_ARM;
case LeggingsPivot -> avatar.luaRuntime.vanilla_model.LEGGINGS;
case LeftLeggingPivot -> avatar.luaRuntime.vanilla_model.LEGGINGS_LEFT_LEG;
case RightLeggingPivot -> avatar.luaRuntime.vanilla_model.LEGGINGS_RIGHT_LEG;
case LeftBootPivot -> avatar.luaRuntime.vanilla_model.BOOTS_LEFT_LEG;
case RightBootPivot -> avatar.luaRuntime.vanilla_model.BOOTS_RIGHT_LEG;
case LeftElytraPivot -> avatar.luaRuntime.vanilla_model.LEFT_ELYTRA;
case RightElytraPivot -> avatar.luaRuntime.vanilla_model.RIGHT_ELYTRA;
default -> null;
};
}

public static EquipmentSlot slotFromPart(ParentType type) {
switch (type){
case Head, HelmetItemPivot, HelmetPivot, Skull -> {
return EquipmentSlot.HEAD;
}
case Body, ChestplatePivot, LeftShoulderPivot, RightShoulderPivot, LeftElytra, RightElytra, ElytraPivot -> {
case Body, ChestplatePivot, LeftShoulderPivot, RightShoulderPivot, LeftElytra, RightElytra, RightElytraPivot, LeftElytraPivot -> {
return EquipmentSlot.CHEST;
}
case LeftArm, LeftItemPivot, LeftSpyglassPivot -> {
Expand Down
Expand Up @@ -314,7 +314,8 @@ 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(LeftElytra, FiguraVec3.of(0, 24, 0), body);
model.addGroup(RightElytra, 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);
Expand Down

0 comments on commit a125d4b

Please sign in to comment.