From b538995e69225a3e936f80ae6cb9ee995c2f5516 Mon Sep 17 00:00:00 2001 From: flogic Date: Thu, 22 Oct 2020 21:00:50 -0600 Subject: [PATCH] WIP Stuff nothing works --- .../client/handler/ChunkAnimationHandler.java | 57 ++++++++++++++----- .../mixin/BuiltChunkStorageMixin.java | 36 ++++++++++++ .../smoothchunks/mixin/ChunkBuilderMixin.java | 35 ++++++++++++ .../mixin/WorldRendererMixin.java | 31 +++++++++- src/main/resources/fabric.mod.json | 2 +- .../resources/smooth-chunks.accesswidener | 6 +- src/main/resources/smooth-chunks.mixins.json | 4 +- 7 files changed, 150 insertions(+), 21 deletions(-) create mode 100644 src/main/java/cc/flogi/dev/smoothchunks/mixin/BuiltChunkStorageMixin.java create mode 100644 src/main/java/cc/flogi/dev/smoothchunks/mixin/ChunkBuilderMixin.java diff --git a/src/main/java/cc/flogi/dev/smoothchunks/client/handler/ChunkAnimationHandler.java b/src/main/java/cc/flogi/dev/smoothchunks/client/handler/ChunkAnimationHandler.java index 0161b55..22b27e9 100644 --- a/src/main/java/cc/flogi/dev/smoothchunks/client/handler/ChunkAnimationHandler.java +++ b/src/main/java/cc/flogi/dev/smoothchunks/client/handler/ChunkAnimationHandler.java @@ -4,13 +4,16 @@ import cc.flogi.dev.smoothchunks.client.config.LoadAnimation; import cc.flogi.dev.smoothchunks.client.config.SmoothChunksConfig; import lombok.AllArgsConstructor; import lombok.Data; +import net.minecraft.client.MinecraftClient; +import net.minecraft.client.render.WorldRenderer; import net.minecraft.client.render.chunk.ChunkBuilder; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.math.BlockPos; -import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.WeakHashMap; +import java.util.stream.Collectors; /** * @author Caden Kriese (flogic) @@ -23,7 +26,7 @@ public final class ChunkAnimationHandler { private final boolean DISABLE_NEARBY; private final WeakHashMap animations = new WeakHashMap<>(); - private final List completedChunks = new ArrayList<>(); +// private final HashMap animations = new HashMap<>(); public ChunkAnimationHandler(SmoothChunksConfig config) { DURATION = config.getDuration() * 1000; @@ -31,36 +34,60 @@ public final class ChunkAnimationHandler { DISABLE_NEARBY = config.isDisableNearby(); } - public void update(ChunkBuilder.BuiltChunk chunk, MatrixStack stack) { - if (completedChunks.contains(chunk.getOrigin())) return; + public void addChunk(ChunkBuilder.BuiltChunk chunk) { + animations.put(chunk, new AnimationController(chunk.getOrigin(), System.currentTimeMillis())); + } + public void updateChunk(WorldRenderer renderer, WorldRenderer.ChunkInfo info, ChunkBuilder.BuiltChunk chunk, MatrixStack stack) { AnimationController controller = animations.get(chunk); + if (controller == null || MinecraftClient.getInstance().getCameraEntity() == null) return; - if (controller == null) { - controller = new AnimationController(chunk.getOrigin(), System.currentTimeMillis()); - animations.put(chunk, controller); - } + // The chunk was not built last frame. +// if () { +// +// } +// if (chunk.rebuildFrame - renderer.frame > -1) { +// addChunk(chunk); +// controller = animations.get(chunk); +// } + + //TODO for disable_nearby, check if dY < radius || dX < radius. Or just check distSq for a minuscule performance hit. double completion = (double) (System.currentTimeMillis() - controller.getStartTime()) / DURATION; completion = Math.min(completion, 1.0); + int chunkY = controller.getFinalPos().getY(); + switch (LOAD_ANIMATION) { default: - case UPWARD: - stack.translate(0, (1 - completion) * controller.getFinalPos().getY(), 0); - break; case DOWNWARD: - stack.translate(0, -(1 - completion) * controller.getFinalPos().getY(), 0); + stack.translate(0, 256 - chunkY - (completion * chunkY), 0); + break; + case UPWARD: + stack.translate(0, -chunkY + (completion * chunkY), 0); break; // case INWARD: // stack.translate(0, (1 - completion) * controller.getFinalPos().getY(), 0); // break; } - if (completion >= 1.0) { - completedChunks.add(chunk.getOrigin()); - animations.remove(chunk); + if (completion >= 1.0) animations.remove(chunk); + } + + private void cullDistantChunks(WorldRenderer renderer) { + List toCull = animations.keySet().stream().filter(chunk -> chunk.rebuildFrame - renderer.frame < -1).collect(Collectors.toList()); +// .forEach(animations::remove); + + if (toCull.size() > 0) { + System.out.printf("Found %d chunks. -- ", toCull.size()); + System.out.printf("Frame difference is %d. -- ", toCull.get(0).rebuildFrame - renderer.frame); + + String xBehind = toCull.get(0).getOrigin().getX() < Objects.requireNonNull(MinecraftClient.getInstance().getCameraEntity()).getBlockPos().getX() ? "behind" : "in-front of"; + String zBehind = toCull.get(0).getOrigin().getZ() < Objects.requireNonNull(MinecraftClient.getInstance().getCameraEntity()).getBlockPos().getZ() ? "behind" : "in-front of"; + + System.out.printf("The chunk is %s you on the x-axis and %s you on the z-axis.\n", xBehind, zBehind); } +// toCull.forEach(animations::remove); } @AllArgsConstructor @Data diff --git a/src/main/java/cc/flogi/dev/smoothchunks/mixin/BuiltChunkStorageMixin.java b/src/main/java/cc/flogi/dev/smoothchunks/mixin/BuiltChunkStorageMixin.java new file mode 100644 index 0000000..1ec3e64 --- /dev/null +++ b/src/main/java/cc/flogi/dev/smoothchunks/mixin/BuiltChunkStorageMixin.java @@ -0,0 +1,36 @@ +package cc.flogi.dev.smoothchunks.mixin; + +import cc.flogi.dev.smoothchunks.client.SmoothChunksClient; +import net.minecraft.client.render.BuiltChunkStorage; +import net.minecraft.client.render.WorldRenderer; +import net.minecraft.client.render.chunk.ChunkBuilder; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; + +/** + * @author Caden Kriese (flogic) + * + * Created on 09/29/2020 + */ +@Mixin(BuiltChunkStorage.class) +public abstract class BuiltChunkStorageMixin { + @Shadow public ChunkBuilder.BuiltChunk[] chunks; + @Final @Shadow protected WorldRenderer worldRenderer; + + @Inject(method = "updateCameraPosition", at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk;setOrigin(III)V"), + locals = LocalCapture.CAPTURE_FAILHARD) + private void updateChunkOrigin(double x, double z, CallbackInfo info, int i, int j, int k, int l, int m, int n, + int o, int p, int q, int r, int s, int t, ChunkBuilder.BuiltChunk builtChunk) { +// if (builtChunk.rebuildFrame == -1 || worldRenderer.frame - builtChunk.rebuildFrame > 2) { +// System.out.println("Chunk became visible, adding to queue."); +// SmoothChunksClient.get().getChunkAnimationHandler().addChunk(builtChunk); +// } + } +} diff --git a/src/main/java/cc/flogi/dev/smoothchunks/mixin/ChunkBuilderMixin.java b/src/main/java/cc/flogi/dev/smoothchunks/mixin/ChunkBuilderMixin.java new file mode 100644 index 0000000..a373fc6 --- /dev/null +++ b/src/main/java/cc/flogi/dev/smoothchunks/mixin/ChunkBuilderMixin.java @@ -0,0 +1,35 @@ +package cc.flogi.dev.smoothchunks.mixin; + +import cc.flogi.dev.smoothchunks.client.SmoothChunksClient; +import net.minecraft.client.render.chunk.ChunkBuilder; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +/** + * @author Caden Kriese (flogic) + * + * Created on 10/07/2020 + */ +@Mixin(ChunkBuilder.BuiltChunk.class) +public abstract class ChunkBuilderMixin { + @Inject( + method = "setOrigin", + at = @At( + value = "INVOKE", +// args = "log=true", + target = "Lnet/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk;clear()V" + ) + ) + public void onSetOrigin(int x, int y, int z, CallbackInfo info) { + ChunkBuilder.BuiltChunk chunk = (ChunkBuilder.BuiltChunk) (Object) this; + +// System.out.println("Running animation on chunk @ (" + x + ", " + y + ", " + z + ")."); +// String xBehind = chunk.getOrigin().getX() < Objects.requireNonNull(MinecraftClient.getInstance().getCameraEntity()).getBlockPos().getX() ? "behind" : "in-front of"; +// String zBehind = chunk.getOrigin().getZ() < Objects.requireNonNull(MinecraftClient.getInstance().getCameraEntity()).getBlockPos().getZ() ? "behind" : "in-front of"; + +// System.out.printf("Animating chunk %s you on the x-axis and %s you on the z-axis.\n", xBehind, zBehind); + SmoothChunksClient.get().getChunkAnimationHandler().addChunk(chunk); + } +} diff --git a/src/main/java/cc/flogi/dev/smoothchunks/mixin/WorldRendererMixin.java b/src/main/java/cc/flogi/dev/smoothchunks/mixin/WorldRendererMixin.java index 4ad71a0..aef809a 100644 --- a/src/main/java/cc/flogi/dev/smoothchunks/mixin/WorldRendererMixin.java +++ b/src/main/java/cc/flogi/dev/smoothchunks/mixin/WorldRendererMixin.java @@ -3,16 +3,21 @@ package cc.flogi.dev.smoothchunks.mixin; import cc.flogi.dev.smoothchunks.client.SmoothChunksClient; import it.unimi.dsi.fastutil.objects.ObjectListIterator; import net.minecraft.client.gl.VertexBuffer; -import net.minecraft.client.render.RenderLayer; -import net.minecraft.client.render.WorldRenderer; +import net.minecraft.client.render.*; import net.minecraft.client.render.chunk.ChunkBuilder; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; +import net.minecraft.util.math.Vec3d; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; +import java.util.Queue; + /** * @author Caden Kriese (flogic) * @@ -20,6 +25,8 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture; */ @Mixin(WorldRenderer.class) public abstract class WorldRendererMixin { + @Shadow private BuiltChunkStorage chunks; + @Inject( method = "renderLayer", at = @At( @@ -30,6 +37,24 @@ public abstract class WorldRendererMixin { private void renderLayerInject(RenderLayer renderLayer, MatrixStack matrixStack, double d, double e, double f, CallbackInfo ci, boolean bl, ObjectListIterator objectListIterator, WorldRenderer.ChunkInfo chunkInfo2, ChunkBuilder.BuiltChunk builtChunk, VertexBuffer vertexBuffer) { - SmoothChunksClient.get().getChunkAnimationHandler().update(builtChunk, matrixStack); + SmoothChunksClient.get().getChunkAnimationHandler().updateChunk((WorldRenderer) (Object) this, chunkInfo2, builtChunk, matrixStack); + } + + @Inject( + method = "setupTerrain", + at = @At( + value = "INVOKE", +// ordinal = 1, +// args = "log=true", + target = "Lit/unimi/dsi/fastutil/objects/ObjectList;add(Ljava/lang/Object;)Z"), + locals = LocalCapture.CAPTURE_FAILHARD) + private void chunkBecomesVisible(Camera camera, Frustum frustum, boolean hasForcedFrustum, int frame, boolean spectator, + CallbackInfo ci, Vec3d vec3d, BlockPos blockPos, ChunkBuilder.BuiltChunk builtChunk, int i, + BlockPos blockPos2, float g, float h, Queue queue, boolean bl, WorldRenderer.ChunkInfo chunkInfo, + ChunkBuilder.BuiltChunk builtChunk3, Direction direction) { +// if (!Arrays.asList(chunks.chunks).contains(builtChunk3)) { +// System.out.println("Chunk became visible, adding to queue."); +// SmoothChunksClient.get().getChunkAnimationHandler().addChunk(builtChunk3); +// } } } diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 01d9e5f..84065e4 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "smooth-chunks", - "version": "@version@", + "version": "${version}", "name": "Smooth Chunks", "description": "Smooth chunk load animations.", "authors": [ diff --git a/src/main/resources/smooth-chunks.accesswidener b/src/main/resources/smooth-chunks.accesswidener index 425f838..2e2edac 100644 --- a/src/main/resources/smooth-chunks.accesswidener +++ b/src/main/resources/smooth-chunks.accesswidener @@ -1,3 +1,7 @@ accessWidener v1 named -accessible class net/minecraft/client/render/WorldRenderer$ChunkInfo \ No newline at end of file +accessible class net/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk$RebuildTask +accessible class net/minecraft/client/render/WorldRenderer$ChunkInfo +accessible field net/minecraft/client/render/WorldRenderer visibleChunks I +accessible field net/minecraft/client/render/WorldRenderer frame I +accessible field net/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk rebuildFrame I \ No newline at end of file diff --git a/src/main/resources/smooth-chunks.mixins.json b/src/main/resources/smooth-chunks.mixins.json index 6435739..de1570b 100644 --- a/src/main/resources/smooth-chunks.mixins.json +++ b/src/main/resources/smooth-chunks.mixins.json @@ -5,7 +5,9 @@ "compatibilityLevel": "JAVA_8", "mixins": [], "client": [ - "WorldRendererMixin" + "WorldRendererMixin", + "ChunkBuilderMixin", + "BuiltChunkStorageMixin" ], "injectors": { "defaultRequire": 1