feat: animated cosmetic textures

This commit is contained in:
Timo Ley 2023-10-29 13:34:50 +01:00
parent 4368abcb2a
commit 13fc26a964
4 changed files with 38 additions and 3 deletions

View file

@ -25,6 +25,7 @@ import net.minecraft.util.Identifier;
import net.minecraft.util.math.Matrix4f; import net.minecraft.util.math.Matrix4f;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.math.Vec3f; import net.minecraft.util.math.Vec3f;
import net.minecraft.util.math.Vector4f;
import net.minecraftforge.fml.ModList; import net.minecraftforge.fml.ModList;
import software.bernie.geckolib3.compat.PatchouliCompat; import software.bernie.geckolib3.compat.PatchouliCompat;
import software.bernie.geckolib3.core.IAnimatable; 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.core.util.Color;
import software.bernie.geckolib3.geo.render.built.GeoBone; import software.bernie.geckolib3.geo.render.built.GeoBone;
import software.bernie.geckolib3.geo.render.built.GeoModel; 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.model.AnimatedGeoModel;
import software.bernie.geckolib3.renderers.geo.IGeoRenderer; import software.bernie.geckolib3.renderers.geo.IGeoRenderer;
import software.bernie.geckolib3.util.EModelRenderCycle; import software.bernie.geckolib3.util.EModelRenderCycle;
@ -51,6 +54,7 @@ public class CosmeticArmorRenderer extends BipedEntityModel<PlayerEntity>
protected float heightScale = 1; protected float heightScale = 1;
protected Matrix4f dispatchedMat = new Matrix4f(); protected Matrix4f dispatchedMat = new Matrix4f();
protected Matrix4f renderEarlyMat = new Matrix4f(); protected Matrix4f renderEarlyMat = new Matrix4f();
protected int currentFrame = 0;
public String headBone = null; public String headBone = null;
public String bodyBone = null; public String bodyBone = null;
@ -116,6 +120,9 @@ public class CosmeticArmorRenderer extends BipedEntityModel<PlayerEntity>
poseStack.translate(0, 24 / 16F, 0); poseStack.translate(0, 24 / 16F, 0);
poseStack.scale(-1, -1, 1); 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.last().pose().copy();
this.dispatchedMat = poseStack.peek().getPositionMatrix().copy(); this.dispatchedMat = poseStack.peek().getPositionMatrix().copy();
@ -410,4 +417,22 @@ public class CosmeticArmorRenderer extends BipedEntityModel<PlayerEntity>
public ICosmetic getCurrentCosmetic() { public ICosmetic getCurrentCosmetic() {
return this.currentArmorItem.getCosmetic(); 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());
}
}
} }

View file

@ -43,6 +43,7 @@ public class CosmeticFeatureRenderer extends ArmorFeatureRenderer<
float netHeadYaw, float netHeadYaw,
float headPitch float headPitch
) { ) {
if (player.isInvisible()) return;
for (ICosmetic c : CosmeticsManager.getCosmeticsForPlayer(player.getUuid())) { for (ICosmetic c : CosmeticsManager.getCosmeticsForPlayer(player.getUuid())) {
if (c.readyToRender()) if (c.readyToRender())
this.renderCosmetic(matrix, buffer, player, light, c, partialTicks); this.renderCosmetic(matrix, buffer, player, light, c, partialTicks);

View file

@ -3,6 +3,7 @@ package net.anvilcraft.anvillib.cosmetics;
import software.bernie.geckolib3.core.IAnimatable; import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.PlayState; import software.bernie.geckolib3.core.PlayState;
import software.bernie.geckolib3.core.builder.AnimationBuilder; 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.controller.AnimationController;
import software.bernie.geckolib3.core.event.predicate.AnimationEvent; import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
import software.bernie.geckolib3.core.manager.AnimationData; import software.bernie.geckolib3.core.manager.AnimationData;
@ -15,7 +16,9 @@ public class CosmeticItem implements IAnimatable {
public CosmeticItem(ICosmetic cosmetic) { public CosmeticItem(ICosmetic cosmetic) {
this.cosmetic = cosmetic; this.cosmetic = cosmetic;
this.cosmetic.addAnimations(animationBuilder); if (cosmetic.getIdleAnimationName() != null) {
this.animationBuilder.addAnimation(cosmetic.getIdleAnimationName(), EDefaultLoopTypes.LOOP);
}
} }
private <P extends IAnimatable> PlayState predicate(AnimationEvent<P> event) { private <P extends IAnimatable> PlayState predicate(AnimationEvent<P> event) {

View file

@ -1,7 +1,6 @@
package net.anvilcraft.anvillib.cosmetics; package net.anvilcraft.anvillib.cosmetics;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import software.bernie.geckolib3.core.builder.AnimationBuilder;
public interface ICosmetic { public interface ICosmetic {
Identifier getAnimationFileLocation(); Identifier getAnimationFileLocation();
@ -34,11 +33,18 @@ public interface ICosmetic {
return null; //leg_right return null; //leg_right
} }
void addAnimations(AnimationBuilder builder); default String getIdleAnimationName() {
return null;
}
default boolean readyToRender() { default boolean readyToRender() {
return true; return true;
} }
Identifier getID(); Identifier getID();
default int getTotalFrames() {
return 1;
}
} }