AzureDoom / AzureLib

Based off Geckolib but now just for my own needs.
MIT License
42 stars 7 forks source link

Animations don't transfer to entity render layer with custom model #59

Closed JayZX535 closed 3 months ago

JayZX535 commented 3 months ago

Greetings!

I'm working on an entity in AzureLib which has both a base model, and a render layer which uses a custom model (same basic bone structure but different cubes, making it compatible with the base entity's animations but allowing it to add additional geometry). Referencing off of Gigaresque and Azure's own AutoGlowing layer, it looks like accepted practice is to call getRenderer().reRender() and substitute getDefaultBakedModel(animatable) instead of the baked model that gets passed in. However, when doing this, the custom model will render but without inheriting any animations, causing it to bind to the base model while t-posing.

This appears to be due to the way that GeoEntityRenderer#actuallyRender() functions, as I copied and modified the code somewhat and was able to create a custom alternative which does allow the model to animate.

if (!isReRender) {
    float headPitch = Mth.lerp(partialTick, animatable.xRotO, animatable.getXRot());
    float motionThreshold = getMotionAnimThreshold(animatable);
    Vec3 velocity = animatable.getDeltaMovement();
    float avgVelocity = (float) (Math.abs(velocity.x) + Math.abs(velocity.z)) / 2f;
    AnimationState<T> animationState = new AnimationState<T>(animatable, limbSwing, limbSwingAmount, partialTick, avgVelocity >= motionThreshold && limbSwingAmount != 0);
    long instanceId = getInstanceId(animatable);

    animationState.setData(DataTickets.TICK, animatable.getTick(animatable));
    animationState.setData(DataTickets.ENTITY, animatable);
    animationState.setData(DataTickets.ENTITY_MODEL_DATA, new EntityModelData(shouldSit, livingEntity != null && livingEntity.isBaby(), -netHeadYaw, -headPitch));
    this.model.addAdditionalStateData(animatable, instanceId, animationState::setData);
    this.model.handleAnimations(animatable, instanceId, animationState);
}

This portion of the code seems to be what prevents animations from being copied, as it does not run on rerender. However, it has a hard reference to the base model via this.model. I removed the !isReRender stipulation from my custom copy and changed this.model to an inputted GeoModel, which I then provided with my custom model from the layer class, resulting in the following.

float headPitch = Mth.lerp(partialTick, animatable.xRotO, animatable.getXRot());
float motionThreshold = getMotionAnimThreshold(animatable);
Vec3 velocity = animatable.getDeltaMovement();
float avgVelocity = (float) (Math.abs(velocity.x) + Math.abs(velocity.z)) / 2f;
AnimationState<T> animationState = new AnimationState<T>(animatable, limbSwing, limbSwingAmount, partialTick, avgVelocity >= motionThreshold && limbSwingAmount != 0);
long instanceId = getInstanceId(animatable);

animationState.setData(DataTickets.TICK, animatable.getTick(animatable));
animationState.setData(DataTickets.ENTITY, animatable);
animationState.setData(DataTickets.ENTITY_MODEL_DATA, new EntityModelData(shouldSit, animatable != null && animatable.isBaby(), -netHeadYaw, -headPitch));
modelIn.addAdditionalStateData(animatable, instanceId, animationState::setData);
modelIn.handleAnimations(animatable, instanceId, animationState);

This then correctly applied the base model animations to the layer.

I am working in the 1.18 Forge version of Azure, unknown if the issue exists for other versions.

AzureDoom commented 3 months ago

Resolved per the discord discussions!