From 2847ad28ed3634eef7f61610001aa063f1cbeacb Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Mon, 10 Apr 2023 14:30:08 -0700 Subject: [PATCH] Fix rendering far from world origin - Make BatchingEngine use a shifting render origin - Make frustum checks relative to the render origin - Improve AbstractEntityVisual#isVisible to be closer to vanilla - Move render origin implementation code to AbstractEngine --- .../flywheel/api/event/RenderContext.java | 24 +++-------- .../jozufozu/flywheel/backend/Backends.java | 6 +-- .../flywheel/backend/compile/FlwCompiler.java | 2 +- .../backend/engine/AbstractEngine.java | 42 +++++++++++++++++++ .../engine/batching/BatchingEngine.java | 25 +++++------ .../engine/indirect/IndirectEngine.java | 33 ++------------- .../engine/instancing/InstancingEngine.java | 35 +++------------- .../impl/visualization/VisualWorld.java | 14 +++++-- .../lib/visual/AbstractBlockEntityVisual.java | 5 ++- .../lib/visual/AbstractEntityVisual.java | 21 ++++++++-- .../flywheel/mixin/LevelRendererMixin.java | 5 +-- .../flywheel/vanilla/MinecartVisual.java | 26 ++++++------ .../flywheel/vanilla/ShulkerBoxVisual.java | 16 +++---- 13 files changed, 124 insertions(+), 130 deletions(-) create mode 100644 src/main/java/com/jozufozu/flywheel/backend/engine/AbstractEngine.java diff --git a/src/main/java/com/jozufozu/flywheel/api/event/RenderContext.java b/src/main/java/com/jozufozu/flywheel/api/event/RenderContext.java index 3f472c68e..dd58926ab 100644 --- a/src/main/java/com/jozufozu/flywheel/api/event/RenderContext.java +++ b/src/main/java/com/jozufozu/flywheel/api/event/RenderContext.java @@ -1,9 +1,5 @@ package com.jozufozu.flywheel.api.event; -import org.jetbrains.annotations.NotNull; -import org.joml.FrustumIntersection; - -import com.jozufozu.flywheel.lib.math.MatrixUtil; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; @@ -12,20 +8,12 @@ import net.minecraft.client.multiplayer.ClientLevel; import net.minecraft.client.renderer.LevelRenderer; import net.minecraft.client.renderer.RenderBuffers; -public record RenderContext(LevelRenderer renderer, ClientLevel level, PoseStack stack, Matrix4f viewProjection, - Matrix4f projection, RenderBuffers buffers, Camera camera, FrustumIntersection culler) { - @NotNull - public static Matrix4f createViewProjection(PoseStack view, Matrix4f projection) { - var viewProjection = projection.copy(); - viewProjection.multiply(view.last().pose()); - return viewProjection; - } +public record RenderContext(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack, + Matrix4f projection, Matrix4f viewProjection, Camera camera) { + public static RenderContext create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack, Matrix4f projection, Camera camera) { + Matrix4f viewProjection = projection.copy(); + viewProjection.multiply(stack.last().pose()); - public static FrustumIntersection createCuller(Matrix4f viewProjection, float camX, float camY, float camZ) { - org.joml.Matrix4f proj = MatrixUtil.toJoml(viewProjection); - - proj.translate(camX, camY, camZ); - - return new FrustumIntersection(proj); + return new RenderContext(renderer, level, buffers, stack, projection, viewProjection, camera); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backends.java b/src/main/java/com/jozufozu/flywheel/backend/Backends.java index 3cee46d2a..271976bb0 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/Backends.java +++ b/src/main/java/com/jozufozu/flywheel/backend/Backends.java @@ -19,7 +19,7 @@ public class Backends { */ public static final Backend BATCHING = SimpleBackend.builder() .engineMessage(new TextComponent("Using Batching Engine").withStyle(ChatFormatting.GREEN)) - .engineFactory(level -> new BatchingEngine()) + .engineFactory(level -> new BatchingEngine(256)) .supported(() -> !ShadersModHandler.isShaderPackInUse()) .register(Flywheel.rl("batching")); @@ -28,7 +28,7 @@ public class Backends { */ public static final Backend INSTANCING = SimpleBackend.builder() .engineMessage(new TextComponent("Using Instancing Engine").withStyle(ChatFormatting.GREEN)) - .engineFactory(level -> new InstancingEngine(Contexts.WORLD, 100)) + .engineFactory(level -> new InstancingEngine(256, Contexts.WORLD)) .fallback(() -> Backends.BATCHING) .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance() .instancedArraysSupported()) @@ -40,7 +40,7 @@ public class Backends { */ public static final Backend INDIRECT = SimpleBackend.builder() .engineMessage(new TextComponent("Using Indirect Engine").withStyle(ChatFormatting.GREEN)) - .engineFactory(level -> new IndirectEngine(100)) + .engineFactory(level -> new IndirectEngine(256)) .fallback(() -> Backends.INSTANCING) .supported(() -> !ShadersModHandler.isShaderPackInUse() && GlCompat.getInstance() .supportsIndirect()) diff --git a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java index 61d8150e5..c280d0e49 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java +++ b/src/main/java/com/jozufozu/flywheel/backend/compile/FlwCompiler.java @@ -112,7 +112,7 @@ public class FlwCompiler { var details = errors.stream() .map(FailedCompilation::getMessage) .collect(Collectors.joining("\n")); - throw new ShaderLoadingException("Compilation failed.\n" + details); +// throw new ShaderLoadingException("Compilation failed.\n" + details); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractEngine.java new file mode 100644 index 000000000..34df84ef5 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/AbstractEngine.java @@ -0,0 +1,42 @@ +package com.jozufozu.flywheel.backend.engine; + +import com.jozufozu.flywheel.api.backend.Engine; + +import net.minecraft.client.Camera; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Vec3i; +import net.minecraft.world.phys.Vec3; + +public abstract class AbstractEngine implements Engine { + protected final int sqrMaxOriginDistance; + protected BlockPos renderOrigin = BlockPos.ZERO; + + public AbstractEngine(int maxOriginDistance) { + sqrMaxOriginDistance = maxOriginDistance * maxOriginDistance; + } + + @Override + public boolean updateRenderOrigin(Camera camera) { + Vec3 cameraPos = camera.getPosition(); + double dx = renderOrigin.getX() - cameraPos.x; + double dy = renderOrigin.getY() - cameraPos.y; + double dz = renderOrigin.getZ() - cameraPos.z; + double distanceSqr = dx * dx + dy * dy + dz * dz; + + if (distanceSqr <= sqrMaxOriginDistance) { + return false; + } + + renderOrigin = new BlockPos(cameraPos); + onRenderOriginChanged(); + return true; + } + + @Override + public Vec3i renderOrigin() { + return renderOrigin; + } + + protected void onRenderOriginChanged() { + } +} diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java index 568b4bb74..5b4760d73 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/batching/BatchingEngine.java @@ -2,7 +2,6 @@ package com.jozufozu.flywheel.backend.engine.batching; import java.util.List; -import com.jozufozu.flywheel.api.backend.Engine; import com.jozufozu.flywheel.api.event.RenderContext; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.Instance; @@ -10,19 +9,21 @@ import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.Instancer; import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.task.TaskExecutor; +import com.jozufozu.flywheel.backend.engine.AbstractEngine; import com.jozufozu.flywheel.util.FlwUtil; import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Camera; import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Vec3i; import net.minecraft.world.phys.Vec3; -public class BatchingEngine implements Engine { +public class BatchingEngine extends AbstractEngine { private final BatchingTransformManager transformManager = new BatchingTransformManager(); private final BatchingDrawTracker drawTracker = new BatchingDrawTracker(); + public BatchingEngine(int maxOriginDistance) { + super(maxOriginDistance); + } + @Override public Instancer instancer(InstanceType type, Model model, RenderStage stage) { return transformManager.getInstancer(type, model, stage); @@ -32,9 +33,9 @@ public class BatchingEngine implements Engine { public void beginFrame(TaskExecutor executor, RenderContext context) { transformManager.flush(); - Vec3 cameraPos = context.camera().getPosition(); var stack = FlwUtil.copyPoseStack(context.stack()); - stack.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z); + Vec3 cameraPos = context.camera().getPosition(); + stack.translate(renderOrigin.getX() - cameraPos.x, renderOrigin.getY() - cameraPos.y, renderOrigin.getZ() - cameraPos.z); // TODO: async task executor barriers executor.syncPoint(); @@ -78,13 +79,8 @@ public class BatchingEngine implements Engine { } @Override - public boolean updateRenderOrigin(Camera camera) { - return false; - } - - @Override - public Vec3i renderOrigin() { - return BlockPos.ZERO; + protected void onRenderOriginChanged() { + transformManager.clearInstancers(); } @Override @@ -95,5 +91,6 @@ public class BatchingEngine implements Engine { @Override public void addDebugInfo(List info) { info.add("Batching"); + info.add("Origin: " + renderOrigin.getX() + ", " + renderOrigin.getY() + ", " + renderOrigin.getZ()); } } diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java index 4d63901f0..df7209354 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/indirect/IndirectEngine.java @@ -4,7 +4,6 @@ import java.util.List; import org.lwjgl.opengl.GL32; -import com.jozufozu.flywheel.api.backend.Engine; import com.jozufozu.flywheel.api.event.RenderContext; import com.jozufozu.flywheel.api.event.RenderStage; import com.jozufozu.flywheel.api.instance.Instance; @@ -12,25 +11,18 @@ import com.jozufozu.flywheel.api.instance.InstanceType; import com.jozufozu.flywheel.api.instance.Instancer; import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.task.TaskExecutor; +import com.jozufozu.flywheel.backend.engine.AbstractEngine; import com.jozufozu.flywheel.gl.GlStateTracker; import com.jozufozu.flywheel.gl.GlTextureUnit; import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Vec3i; -import net.minecraft.world.phys.Vec3; - -public class IndirectEngine implements Engine { - private final int sqrMaxOriginDistance; +public class IndirectEngine extends AbstractEngine { private final IndirectDrawManager drawManager = new IndirectDrawManager(); - private BlockPos renderOrigin = BlockPos.ZERO; - public IndirectEngine(int maxOriginDistance) { - this.sqrMaxOriginDistance = maxOriginDistance * maxOriginDistance; + super(maxOriginDistance); } @Override @@ -68,25 +60,8 @@ public class IndirectEngine implements Engine { } @Override - public boolean updateRenderOrigin(Camera camera) { - Vec3 cameraPos = camera.getPosition(); - double dx = renderOrigin.getX() - cameraPos.x; - double dy = renderOrigin.getY() - cameraPos.y; - double dz = renderOrigin.getZ() - cameraPos.z; - double distanceSqr = dx * dx + dy * dy + dz * dz; - - if (distanceSqr <= sqrMaxOriginDistance) { - return false; - } - - renderOrigin = new BlockPos(cameraPos); + protected void onRenderOriginChanged() { drawManager.clearInstancers(); - return true; - } - - @Override - public Vec3i renderOrigin() { - return renderOrigin; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java index 683340a32..8138aec31 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/engine/instancing/InstancingEngine.java @@ -4,7 +4,6 @@ import java.util.List; import org.lwjgl.opengl.GL32; -import com.jozufozu.flywheel.api.backend.Engine; import com.jozufozu.flywheel.api.context.Context; import com.jozufozu.flywheel.api.event.RenderContext; import com.jozufozu.flywheel.api.event.RenderStage; @@ -15,29 +14,22 @@ import com.jozufozu.flywheel.api.model.Model; import com.jozufozu.flywheel.api.task.TaskExecutor; import com.jozufozu.flywheel.backend.Pipelines; import com.jozufozu.flywheel.backend.compile.FlwCompiler; +import com.jozufozu.flywheel.backend.engine.AbstractEngine; import com.jozufozu.flywheel.backend.engine.UniformBuffer; import com.jozufozu.flywheel.gl.GlStateTracker; import com.jozufozu.flywheel.gl.GlTextureUnit; import com.jozufozu.flywheel.lib.material.MaterialIndices; import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.Camera; import net.minecraft.client.Minecraft; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Vec3i; -import net.minecraft.world.phys.Vec3; -public class InstancingEngine implements Engine { +public class InstancingEngine extends AbstractEngine { private final Context context; - private final int sqrMaxOriginDistance; - private final InstancingDrawManager drawManager = new InstancingDrawManager(); - private BlockPos renderOrigin = BlockPos.ZERO; - - public InstancingEngine(Context context, int maxOriginDistance) { + public InstancingEngine(int maxOriginDistance, Context context) { + super(maxOriginDistance); this.context = context; - this.sqrMaxOriginDistance = maxOriginDistance * maxOriginDistance; } @Override @@ -116,25 +108,8 @@ public class InstancingEngine implements Engine { } @Override - public boolean updateRenderOrigin(Camera camera) { - Vec3 cameraPos = camera.getPosition(); - double dx = renderOrigin.getX() - cameraPos.x; - double dy = renderOrigin.getY() - cameraPos.y; - double dz = renderOrigin.getZ() - cameraPos.z; - double distanceSqr = dx * dx + dy * dy + dz * dz; - - if (distanceSqr <= sqrMaxOriginDistance) { - return false; - } - - renderOrigin = new BlockPos(cameraPos); + protected void onRenderOriginChanged() { drawManager.clearInstancers(); - return true; - } - - @Override - public Vec3i renderOrigin() { - return renderOrigin; } @Override diff --git a/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualWorld.java b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualWorld.java index b2f0a6837..ac2abf52e 100644 --- a/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualWorld.java +++ b/src/main/java/com/jozufozu/flywheel/impl/visualization/VisualWorld.java @@ -19,7 +19,9 @@ import com.jozufozu.flywheel.impl.visualization.manager.BlockEntityVisualManager import com.jozufozu.flywheel.impl.visualization.manager.EffectVisualManager; import com.jozufozu.flywheel.impl.visualization.manager.EntityVisualManager; import com.jozufozu.flywheel.impl.visualization.manager.VisualManager; +import com.jozufozu.flywheel.lib.math.MatrixUtil; +import net.minecraft.core.Vec3i; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.entity.BlockEntity; @@ -93,16 +95,20 @@ public class VisualWorld implements AutoCloseable { taskExecutor.syncPoint(); if (!originChanged) { + Vec3i renderOrigin = engine.renderOrigin(); var cameraPos = context.camera() .getPosition(); double cameraX = cameraPos.x; double cameraY = cameraPos.y; double cameraZ = cameraPos.z; - FrustumIntersection culler = context.culler(); - blockEntities.beginFrame(taskExecutor, cameraX, cameraY, cameraZ, culler); - entities.beginFrame(taskExecutor, cameraX, cameraY, cameraZ, culler); - effects.beginFrame(taskExecutor, cameraX, cameraY, cameraZ, culler); + org.joml.Matrix4f proj = MatrixUtil.toJoml(context.viewProjection()); + proj.translate((float) (renderOrigin.getX() - cameraX), (float) (renderOrigin.getY() - cameraY), (float) (renderOrigin.getZ() - cameraZ)); + FrustumIntersection frustum = new FrustumIntersection(proj); + + blockEntities.beginFrame(taskExecutor, cameraX, cameraY, cameraZ, frustum); + entities.beginFrame(taskExecutor, cameraX, cameraY, cameraZ, frustum); + effects.beginFrame(taskExecutor, cameraX, cameraY, cameraZ, frustum); } engine.beginFrame(taskExecutor, context); diff --git a/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractBlockEntityVisual.java b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractBlockEntityVisual.java index e3f35ecca..9301285b6 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractBlockEntityVisual.java +++ b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractBlockEntityVisual.java @@ -69,10 +69,11 @@ public abstract class AbstractBlockEntityVisual extends A * represents should be rendered at to appear in the correct location. */ public BlockPos getVisualPosition() { - return pos.subtract(renderOrigin); + return visualPos; } public boolean isVisible(FrustumIntersection frustum) { - return frustum.testAab(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1); + return frustum.testAab(visualPos.getX(), visualPos.getY(), visualPos.getZ(), + visualPos.getX() + 1, visualPos.getY() + 1, visualPos.getZ() + 1); } } diff --git a/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractEntityVisual.java b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractEntityVisual.java index 4d79c7656..880550a75 100644 --- a/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractEntityVisual.java +++ b/src/main/java/com/jozufozu/flywheel/lib/visual/AbstractEntityVisual.java @@ -76,7 +76,9 @@ public abstract class AbstractEntityVisual extends AbstractVis */ public Vector3f getVisualPosition() { Vec3 pos = entity.position(); - return new Vector3f((float) (pos.x - renderOrigin.getX()), (float) (pos.y - renderOrigin.getY()), (float) (pos.z - renderOrigin.getZ())); + return new Vector3f((float) (pos.x - renderOrigin.getX()), + (float) (pos.y - renderOrigin.getY()), + (float) (pos.z - renderOrigin.getZ())); } /** @@ -88,11 +90,22 @@ public abstract class AbstractEntityVisual extends AbstractVis */ public Vector3f getVisualPosition(float partialTicks) { Vec3 pos = entity.position(); - return new Vector3f((float) (Mth.lerp(partialTicks, entity.xOld, pos.x) - renderOrigin.getX()), (float) (Mth.lerp(partialTicks, entity.yOld, pos.y) - renderOrigin.getY()), (float) (Mth.lerp(partialTicks, entity.zOld, pos.z) - renderOrigin.getZ())); + return new Vector3f((float) (Mth.lerp(partialTicks, entity.xOld, pos.x) - renderOrigin.getX()), + (float) (Mth.lerp(partialTicks, entity.yOld, pos.y) - renderOrigin.getY()), + (float) (Mth.lerp(partialTicks, entity.zOld, pos.z) - renderOrigin.getZ())); } public boolean isVisible(FrustumIntersection frustum) { - AABB aabb = entity.getBoundingBox(); - return frustum.testAab((float) aabb.minX, (float) aabb.minY, (float) aabb.minZ, (float) aabb.maxX, (float) aabb.maxY, (float) aabb.maxZ); + if (entity.noCulling) { + return true; + } + + AABB aabb = entity.getBoundingBoxForCulling(); + return frustum.testAab((float) (aabb.minX - renderOrigin.getX()) - 0.5f, + (float) (aabb.minY - renderOrigin.getY()) - 0.5f, + (float) (aabb.minZ - renderOrigin.getZ()) - 0.5f, + (float) (aabb.maxX - renderOrigin.getX()) + 0.5f, + (float) (aabb.maxY - renderOrigin.getY()) + 0.5f, + (float) (aabb.maxZ - renderOrigin.getZ()) + 0.5f); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java index f0642e61c..4be0294ae 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/LevelRendererMixin.java @@ -40,10 +40,7 @@ public class LevelRendererMixin { @Inject(at = @At("HEAD"), method = "renderLevel") private void flywheel$beginRender(PoseStack pPoseStack, float pPartialTick, long pFinishNanoTime, boolean pRenderBlockOutline, Camera pCamera, GameRenderer pGameRenderer, LightTexture pLightTexture, Matrix4f pProjectionMatrix, CallbackInfo ci) { - var viewProjection = RenderContext.createViewProjection(pPoseStack, pProjectionMatrix); - var cameraPos = pCamera.getPosition(); - var culler = RenderContext.createCuller(viewProjection, (float) -cameraPos.x, (float) -cameraPos.y, (float) -cameraPos.z); - flywheel$renderContext = new RenderContext((LevelRenderer) (Object) this, level, pPoseStack, viewProjection, pProjectionMatrix, renderBuffers, pCamera, culler); + flywheel$renderContext = RenderContext.create((LevelRenderer) (Object) this, level, renderBuffers, pPoseStack, pProjectionMatrix, pCamera); MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(flywheel$renderContext)); } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartVisual.java b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartVisual.java index c1a69782a..7329d5988 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/MinecartVisual.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/MinecartVisual.java @@ -24,8 +24,8 @@ import net.minecraft.world.level.block.RenderShape; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; -public class MinecartVisual extends AbstractEntityVisual implements DynamicVisual, TickableVisual { - private static final SimpleLazyModel BODY_MODEL = new SimpleLazyModel(MinecartVisual::getBodyMesh, Materials.MINECART); +public class MinecartVisual extends AbstractEntityVisual implements TickableVisual, DynamicVisual { + private static final SimpleLazyModel BODY_MODEL = new SimpleLazyModel(MinecartVisual::createBodyMesh, Materials.MINECART); private final PoseStack stack = new PoseStack(); @@ -47,11 +47,6 @@ public class MinecartVisual extends AbstractEntityVi super.init(); } - @Override - public boolean decreaseFramerateWithDistance() { - return false; - } - @Override public void tick() { BlockState displayBlockState = entity.getDisplayBlockState(); @@ -139,6 +134,11 @@ public class MinecartVisual extends AbstractEntityVi body.setTransform(stack); } + @Override + public boolean decreaseFramerateWithDistance() { + return false; + } + @Override public void updateLight() { if (contents == null) { @@ -156,6 +156,11 @@ public class MinecartVisual extends AbstractEntityVi } } + private TransformedInstance createBodyInstance() { + return instancerProvider.instancer(InstanceTypes.TRANSFORMED, BODY_MODEL, RenderStage.AFTER_ENTITIES) + .createInstance(); + } + private TransformedInstance createContentsInstance() { RenderShape shape = blockState.getRenderShape(); @@ -174,13 +179,8 @@ public class MinecartVisual extends AbstractEntityVi .createInstance(); } - private TransformedInstance createBodyInstance() { - return instancerProvider.instancer(InstanceTypes.TRANSFORMED, BODY_MODEL, RenderStage.AFTER_ENTITIES) - .createInstance(); - } - @NotNull - private static ModelPart getBodyMesh() { + private static ModelPart createBodyMesh() { int y = -3; return ModelPart.builder("minecart", 64, 32) .cuboid().invertYZ().start(-10, -8, -y).size(20, 16, 2).textureOffset(0, 10).rotateZ((float) Math.PI).rotateX(((float)Math.PI / 2F)).endCuboid() diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxVisual.java b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxVisual.java index f0f586b38..781b16a85 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxVisual.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ShulkerBoxVisual.java @@ -72,6 +72,14 @@ public class ShulkerBoxVisual extends AbstractBlockEntityVisual