Skip to content

Commit

Permalink
Fix a handful of broken animations (#868)
Browse files Browse the repository at this point in the history
* Fix warning

* Improve animated sprite tracking

* Fix NPE in animation code

* Fix animations for abnormally rendered items

* Swap Stack for ArrayDeque
  • Loading branch information
RecursivePineapple authored Feb 18, 2025
1 parent f9b9873 commit 67c8628
Show file tree
Hide file tree
Showing 8 changed files with 94 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ public interface ITexturesCache {

Set<IIcon> getRenderedTextures();
void enableTextureTracking();
void track(IPatchedTextureAtlasSprite sprite);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.gtnewhorizons.angelica.utils;

import java.util.ArrayDeque;

import com.gtnewhorizons.angelica.mixins.interfaces.IPatchedTextureAtlasSprite;
import com.gtnewhorizons.angelica.mixins.interfaces.ITexturesCache;
import net.minecraft.client.Minecraft;
Expand Down Expand Up @@ -28,4 +30,26 @@ public static void markBlockTextureForUpdate(IIcon icon, IBlockAccess blockAcces
}
}
}

private final static ThreadLocal<ArrayDeque<ITexturesCache>> TEXTURE_CACHE_STACK = ThreadLocal.withInitial(ArrayDeque::new);

public static void onSpriteUsed(IPatchedTextureAtlasSprite sprite) {
ArrayDeque<ITexturesCache> stack = TEXTURE_CACHE_STACK.get();

if (stack == null || stack.isEmpty()) {
// icon was used outside of chunk building, it's probably an item in an inventory or something
sprite.markNeedsAnimationUpdate();
return;
}

stack.peek().track(sprite);
}

public static void pushCache(ITexturesCache cache) {
TEXTURE_CACHE_STACK.get().push(cache);
}

public static void popCache() {
TEXTURE_CACHE_STACK.get().pop();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import com.gtnewhorizons.angelica.mixins.interfaces.ITexturesCache;
import com.gtnewhorizons.angelica.rendering.AngelicaBlockSafetyRegistry;
import com.gtnewhorizons.angelica.rendering.AngelicaRenderQueue;
import com.gtnewhorizons.angelica.utils.AnimationsRenderUtils;
import it.unimi.dsi.fastutil.longs.LongArrayFIFOQueue;
import me.jellysquid.mods.sodium.client.SodiumClientMod;
import me.jellysquid.mods.sodium.client.render.chunk.ChunkGraphicsState;
Expand Down Expand Up @@ -132,7 +133,10 @@ public ChunkBuildResult<T> performBuild(ChunkRenderCacheLocal cache, ChunkBuildB

final WorldSlice slice = cache.getWorldSlice();
final RenderBlocks renderBlocks = new RenderBlocks(slice);
if(renderBlocks instanceof ITexturesCache) ((ITexturesCache)renderBlocks).enableTextureTracking();
if(renderBlocks instanceof ITexturesCache textureCache) {
textureCache.enableTextureTracking();
AnimationsRenderUtils.pushCache(textureCache);
}

final int baseX = this.render.getOriginX();
final int baseY = this.render.getOriginY();
Expand Down Expand Up @@ -217,6 +221,10 @@ public ChunkBuildResult<T> performBuild(ChunkRenderCacheLocal cache, ChunkBuildB
}
}

if(renderBlocks instanceof ITexturesCache) {
AnimationsRenderUtils.popCache();
}

handleRenderBlocksTextures(renderBlocks, renderData);

if(hasMainThreadBlocks) {
Expand Down Expand Up @@ -263,7 +271,10 @@ private void performMainBuild(ChunkRenderCacheLocal cache, ChunkBuildBuffers buf
final int baseZ = this.render.getOriginZ();
final BlockPos renderOffset = this.offset;
final RenderBlocks rb = new RenderBlocks(slice.getWorld());
if(rb instanceof ITexturesCache) ((ITexturesCache)rb).enableTextureTracking();
if(rb instanceof ITexturesCache textureCache) {
textureCache.enableTextureTracking();
AnimationsRenderUtils.pushCache(textureCache);
}
while(!mainThreadBlocks.isEmpty()) {
final long longPos = mainThreadBlocks.dequeueLong();
if (cancellationSource.isCancelled()) {
Expand Down Expand Up @@ -303,6 +314,10 @@ private void performMainBuild(ChunkRenderCacheLocal cache, ChunkBuildBuffers buf
if(AngelicaConfig.enableIris) buffers.iris$resetBlockContext();
}

if(rb instanceof ITexturesCache) {
AnimationsRenderUtils.popCache();
}

handleRenderBlocksTextures(rb, renderData);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public abstract class MixinMinecraft {
angelica$lastFrameTime = time;
}

@WrapOperation(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/Display;sync(I)V"))
@WrapOperation(method = "runGameLoop", at = @At(value = "INVOKE", target = "Lorg/lwjgl/opengl/Display;sync(I)V", remap = false))
private void angelica$noopFPSLimiter(int fps, Operation<Void> original) {
if (AngelicaConfig.sleepBeforeSwap) return;
original.call(fps);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.mixins.early.angelica.animation;

import com.gtnewhorizons.angelica.mixins.interfaces.IPatchedTextureAtlasSprite;
import com.gtnewhorizons.angelica.mixins.interfaces.ITexturesCache;
import net.minecraft.util.IIcon;
import net.minecraft.world.ChunkCache;
Expand All @@ -23,4 +24,9 @@ public HashSet<IIcon> getRenderedTextures() {
public void enableTextureTracking() {

}

@Override
public void track(IPatchedTextureAtlasSprite sprite) {

}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.gtnewhorizons.angelica.mixins.early.angelica.animation;

import com.gtnewhorizons.angelica.mixins.interfaces.IPatchedTextureAtlasSprite;
import com.gtnewhorizons.angelica.mixins.interfaces.ITexturesCache;
import com.gtnewhorizons.angelica.utils.AnimationsRenderUtils;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;
Expand Down Expand Up @@ -38,36 +39,36 @@ public class MixinRenderBlocks implements ITexturesCache {
* apply Occlusion Querry (Basically that means that we will only mark those textures for update that are
* visible (on the viewport) at the moment)
*/
@Inject(method = "*(Lnet/minecraft/block/Block;DDDLnet/minecraft/util/IIcon;)V", at = @At("HEAD"))
@Inject(method = {
"renderFaceYNeg",
"renderFaceYPos",
"renderFaceZNeg",
"renderFaceZPos",
"renderFaceXNeg",
"renderFaceXPos"
}, at = @At("HEAD"))
public void angelica$beforeRenderFace(Block p_147761_1_, double p_147761_2_, double p_147761_4_,
double p_147761_6_, IIcon icon, CallbackInfo ci) {
if (overrideBlockTexture != null) {
icon = overrideBlockTexture;
}

AnimationsRenderUtils.markBlockTextureForUpdate(icon, blockAccess);

if(this.enableSpriteTracking)
this.renderedSprites.add(icon);
}
if (icon != null) {
AnimationsRenderUtils.markBlockTextureForUpdate(icon, blockAccess);

@Inject(method = "renderBlockFire", at = @At("HEAD"))
public void angelica$markFireBlockAnimationForUpdate(BlockFire instance, int x, int y, int z,
CallbackInfoReturnable<Boolean> cir) {
if(this.enableSpriteTracking) {
this.renderedSprites.add(instance.getFireIcon(0));
this.renderedSprites.add(instance.getFireIcon(1));
if(this.enableSpriteTracking) {
this.renderedSprites.add(icon);
}
}
AnimationsRenderUtils.markBlockTextureForUpdate(instance.getFireIcon(0), blockAccess);
AnimationsRenderUtils.markBlockTextureForUpdate(instance.getFireIcon(1), blockAccess);
}

@ModifyReturnValue(method = "getBlockIconFromSideAndMetadata", at = @At("RETURN"))
public IIcon angelica$markBlockSideAnimationForUpdate(IIcon icon, Block p_147787_1_, int p_147787_2_, int p_147787_3_) {
@ModifyReturnValue(method = "getIconSafe", at = @At("RETURN"))
public IIcon angelica$markBlockSideAnimationForUpdate(IIcon icon) {
AnimationsRenderUtils.markBlockTextureForUpdate(icon, blockAccess);

if(this.enableSpriteTracking)
if(this.enableSpriteTracking) {
this.renderedSprites.add(icon);
}

return icon;
}
Expand All @@ -81,4 +82,11 @@ public Set<IIcon> getRenderedTextures() {
public void enableTextureTracking() {
enableSpriteTracking = true;
}

@Override
public void track(IPatchedTextureAtlasSprite sprite) {
if(this.enableSpriteTracking) {
renderedSprites.add((IIcon) sprite);
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package com.gtnewhorizons.angelica.mixins.early.angelica.animation;

import com.gtnewhorizons.angelica.mixins.interfaces.IPatchedTextureAtlasSprite;
import com.gtnewhorizons.angelica.mixins.interfaces.ISpriteExt;
import com.gtnewhorizons.angelica.utils.AnimationsRenderUtils;
import com.llamalad7.mixinextras.injector.ModifyReturnValue;

import net.minecraft.block.BlockPortal;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.resources.data.AnimationMetadataSection;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At;

import java.util.List;

Expand Down Expand Up @@ -54,4 +60,13 @@ public void updateAnimationsDryRun() {
this.tickCounter = 0;
}
}

@ModifyReturnValue(method = "getMinU", at = @At("RETURN"))
private float angelica$onUVAccessed(float value) {
if (((ISpriteExt)this).isAnimation()) {
AnimationsRenderUtils.onSpriteUsed(this);
needsAnimationUpdate = true;
}
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,9 @@ public Set<IIcon> getRenderedTextures() {
public void enableTextureTracking() {

}

@Override
public void track(IPatchedTextureAtlasSprite sprite) {

}
}

0 comments on commit 67c8628

Please sign in to comment.