From 13fc26a964a091265953d281fd19fd260bb81dcf Mon Sep 17 00:00:00 2001 From: Timo Ley Date: Sun, 29 Oct 2023 13:34:50 +0100 Subject: [PATCH] feat: animated cosmetic textures --- .../cosmetics/CosmeticArmorRenderer.java | 25 +++++++++++++++++++ .../cosmetics/CosmeticFeatureRenderer.java | 1 + .../anvillib/cosmetics/CosmeticItem.java | 5 +++- .../anvillib/cosmetics/ICosmetic.java | 10 ++++++-- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticArmorRenderer.java b/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticArmorRenderer.java index 9e7eed3..7dd7aa4 100644 --- a/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticArmorRenderer.java +++ b/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticArmorRenderer.java @@ -25,6 +25,7 @@ import net.minecraft.util.Identifier; import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3f; +import net.minecraft.util.math.Vector4f; import net.minecraftforge.fml.ModList; import software.bernie.geckolib3.compat.PatchouliCompat; import software.bernie.geckolib3.core.IAnimatable; @@ -36,6 +37,8 @@ import software.bernie.geckolib3.core.processor.IBone; import software.bernie.geckolib3.core.util.Color; import software.bernie.geckolib3.geo.render.built.GeoBone; import software.bernie.geckolib3.geo.render.built.GeoModel; +import software.bernie.geckolib3.geo.render.built.GeoQuad; +import software.bernie.geckolib3.geo.render.built.GeoVertex; import software.bernie.geckolib3.model.AnimatedGeoModel; import software.bernie.geckolib3.renderers.geo.IGeoRenderer; import software.bernie.geckolib3.util.EModelRenderCycle; @@ -51,6 +54,7 @@ public class CosmeticArmorRenderer extends BipedEntityModel protected float heightScale = 1; protected Matrix4f dispatchedMat = new Matrix4f(); protected Matrix4f renderEarlyMat = new Matrix4f(); + protected int currentFrame = 0; public String headBone = null; public String bodyBone = null; @@ -116,6 +120,9 @@ public class CosmeticArmorRenderer extends BipedEntityModel poseStack.translate(0, 24 / 16F, 0); poseStack.scale(-1, -1, 1); + double currentTick = entityLiving.age; // TODO: Custom frametime/animation speed + currentFrame = ((int)(currentTick * 1.0F)) % this.getCurrentCosmetic().getTotalFrames();; + //this.dispatchedMat = poseStack.last().pose().copy(); this.dispatchedMat = poseStack.peek().getPositionMatrix().copy(); @@ -410,4 +417,22 @@ public class CosmeticArmorRenderer extends BipedEntityModel public ICosmetic getCurrentCosmetic() { return this.currentArmorItem.getCosmetic(); } + + public float calcVOffset(float v) { + float totalFrames = (float)this.getCurrentCosmetic().getTotalFrames(); + float currentTextureOffset = (float)currentFrame / totalFrames; + return (v / totalFrames) + currentTextureOffset; + } + + @Override + public void createVerticesOfQuad(GeoQuad quad, Matrix4f poseState, Vec3f normal, VertexConsumer buffer, + int packedLight, int packedOverlay, float red, float green, float blue, float alpha) { + for (GeoVertex vertex : quad.vertices) { + Vector4f vector4f = new Vector4f(vertex.position.getX(), vertex.position.getY(), vertex.position.getZ(), 1); + + vector4f.transform(poseState); + buffer.vertex(vector4f.getX(), vector4f.getY(), vector4f.getZ(), red, green, blue, alpha, vertex.textureU, + calcVOffset(vertex.textureV), packedOverlay, packedLight, normal.getX(), normal.getY(), normal.getZ()); + } + } } diff --git a/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticFeatureRenderer.java b/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticFeatureRenderer.java index b3e5d19..1073fbb 100644 --- a/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticFeatureRenderer.java +++ b/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticFeatureRenderer.java @@ -43,6 +43,7 @@ public class CosmeticFeatureRenderer extends ArmorFeatureRenderer< float netHeadYaw, float headPitch ) { + if (player.isInvisible()) return; for (ICosmetic c : CosmeticsManager.getCosmeticsForPlayer(player.getUuid())) { if (c.readyToRender()) this.renderCosmetic(matrix, buffer, player, light, c, partialTicks); diff --git a/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticItem.java b/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticItem.java index 637d62f..6aa3b57 100644 --- a/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticItem.java +++ b/src/main/java/net/anvilcraft/anvillib/cosmetics/CosmeticItem.java @@ -3,6 +3,7 @@ package net.anvilcraft.anvillib.cosmetics; import software.bernie.geckolib3.core.IAnimatable; import software.bernie.geckolib3.core.PlayState; import software.bernie.geckolib3.core.builder.AnimationBuilder; +import software.bernie.geckolib3.core.builder.ILoopType.EDefaultLoopTypes; import software.bernie.geckolib3.core.controller.AnimationController; import software.bernie.geckolib3.core.event.predicate.AnimationEvent; import software.bernie.geckolib3.core.manager.AnimationData; @@ -15,7 +16,9 @@ public class CosmeticItem implements IAnimatable { public CosmeticItem(ICosmetic cosmetic) { this.cosmetic = cosmetic; - this.cosmetic.addAnimations(animationBuilder); + if (cosmetic.getIdleAnimationName() != null) { + this.animationBuilder.addAnimation(cosmetic.getIdleAnimationName(), EDefaultLoopTypes.LOOP); + } } private

PlayState predicate(AnimationEvent

event) { diff --git a/src/main/java/net/anvilcraft/anvillib/cosmetics/ICosmetic.java b/src/main/java/net/anvilcraft/anvillib/cosmetics/ICosmetic.java index b0db9b9..3232bcc 100644 --- a/src/main/java/net/anvilcraft/anvillib/cosmetics/ICosmetic.java +++ b/src/main/java/net/anvilcraft/anvillib/cosmetics/ICosmetic.java @@ -1,7 +1,6 @@ package net.anvilcraft.anvillib.cosmetics; import net.minecraft.util.Identifier; -import software.bernie.geckolib3.core.builder.AnimationBuilder; public interface ICosmetic { Identifier getAnimationFileLocation(); @@ -34,11 +33,18 @@ public interface ICosmetic { return null; //leg_right } - void addAnimations(AnimationBuilder builder); + default String getIdleAnimationName() { + return null; + } default boolean readyToRender() { return true; } Identifier getID(); + + default int getTotalFrames() { + return 1; + } + }