From cfff806df48d79e10c881749654eeae08f4b0455 Mon Sep 17 00:00:00 2001 From: JozsefA Date: Mon, 8 Feb 2021 21:17:25 -0800 Subject: [PATCH] some micro optimizations. cache hot getters. reduce number of calls to getBeltFacing() in BeltRenderer. preserve floating point accuracy over (insanely) long play times. rotate some normals and light some quads. --- .../category/animations/AnimatedKinetics.java | 2 +- .../category/animations/AnimatedSpout.java | 4 +- .../contraptions/base/KineticTileEntity.java | 6 -- .../clock/CuckooClockTileEntity.java | 4 +- .../crafter/MechanicalCrafterRenderer.java | 3 +- .../particle/RotationIndicatorParticle.java | 3 +- .../processing/BasinTileEntity.java | 23 ++------ .../relays/belt/BeltRenderer.java | 21 +++---- .../relays/belt/BeltTileEntity.java | 17 ++++-- .../tools/SandPaperItemRenderer.java | 2 +- .../block/mechanicalArm/ArmRenderer.java | 5 +- .../simibubi/create/events/ClientEvents.java | 5 +- .../create/foundation/config/CClient.java | 6 ++ .../render/FastRenderDispatcher.java | 3 +- .../foundation/render/SuperByteBuffer.java | 59 +++++++++++++------ .../foundation/render/gl/BasicProgram.java | 2 +- .../foundation/render/gl/backend/Backend.java | 10 +++- .../instancing/InstancedTileRenderer.java | 2 +- .../utility/AnimationTickHolder.java | 15 ++++- 19 files changed, 109 insertions(+), 83 deletions(-) diff --git a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedKinetics.java b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedKinetics.java index 4339372d5..003cf9333 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedKinetics.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedKinetics.java @@ -11,7 +11,7 @@ import net.minecraft.util.Direction.Axis; public abstract class AnimatedKinetics implements IDrawable { public static float getCurrentAngle() { - return ((AnimationTickHolder.ticks + AnimationTickHolder.getPartialTicks()) * 4f) % 360; + return ((AnimationTickHolder.getRenderTick()) * 4f) % 360; } protected BlockState shaft(Axis axis) { diff --git a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedSpout.java b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedSpout.java index ad1ae4522..52eed284e 100644 --- a/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedSpout.java +++ b/src/main/java/com/simibubi/create/compat/jei/category/animations/AnimatedSpout.java @@ -15,8 +15,6 @@ import net.minecraftforge.fluids.FluidStack; import java.util.List; -import static com.simibubi.create.foundation.utility.AnimationTickHolder.ticks; - public class AnimatedSpout extends AnimatedKinetics { private List fluids; @@ -38,7 +36,7 @@ public class AnimatedSpout extends AnimatedKinetics { .scale(scale) .render(); - float cycle = (ticks + AnimationTickHolder.getPartialTicks()) % 30; + float cycle = AnimationTickHolder.getRenderTick() % 30; float squeeze = cycle < 20 ? MathHelper.sin((float) (cycle / 20f * Math.PI)) : 0; squeeze *= 20; diff --git a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java index 2eaa1c517..7ed35759a 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/base/KineticTileEntity.java @@ -26,7 +26,6 @@ import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.Direction; import net.minecraft.util.Direction.AxisDirection; -import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; @@ -463,11 +462,6 @@ public abstract class KineticTileEntity extends SmartTileEntity return overStressed; } - @Override - public AxisAlignedBB getRenderBoundingBox() { - return super.getRenderBoundingBox(); - } - @Override public double getMaxRenderDistanceSquared() { return 16384.0D; // TODO: make this a config option diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockTileEntity.java index 2d0a4c1ec..bc2d77826 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/clock/CuckooClockTileEntity.java @@ -92,9 +92,9 @@ public class CuckooClockTileEntity extends KineticTileEntity { moveHands(hours, minutes); if (animationType == Animation.NONE) { - if (AnimationTickHolder.ticks % 32 == 0) + if (AnimationTickHolder.getTicks() % 32 == 0) playSound(SoundEvents.BLOCK_NOTE_BLOCK_HAT, 1 / 16f, 2f); - else if (AnimationTickHolder.ticks % 16 == 0) + else if (AnimationTickHolder.getTicks() % 16 == 0) playSound(SoundEvents.BLOCK_NOTE_BLOCK_HAT, 1 / 16f, 1.5f); } else { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterRenderer.java index 5dd5581f7..6617e7a91 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/crafter/MechanicalCrafterRenderer.java @@ -6,7 +6,6 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.AllSpriteShifts; import com.simibubi.create.content.contraptions.components.crafter.MechanicalCrafterTileEntity.Phase; import com.simibubi.create.content.contraptions.components.crafter.RecipeGridHandler.GroupedItems; -import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.render.FastRenderDispatcher; import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; @@ -178,7 +177,7 @@ public class MechanicalCrafterRenderer extends SafeTileEntityRenderer { ms.push(); - Vec3i directionVec = te.getBeltFacing() - .getDirectionVec(); + Direction beltFacing = te.getBeltFacing(); + Vec3i directionVec = beltFacing + .getDirectionVec(); Vec3d beltStartOffset = new Vec3d(directionVec).scale(-.5) .add(.5, 13 / 16f + .125f, .5); ms.translate(beltStartOffset.x, beltStartOffset.y, beltStartOffset.z); BeltSlope slope = te.getBlockState() .get(BeltBlock.SLOPE); int verticality = slope == BeltSlope.DOWNWARD ? -1 : slope == BeltSlope.UPWARD ? 1 : 0; - boolean slopeAlongX = te.getBeltFacing() - .getAxis() == Axis.X; + boolean slopeAlongX = beltFacing + .getAxis() == Axis.X; for (TransportedItemStack transported : te.getInventory() .getTransportedItems()) { @@ -205,16 +206,16 @@ public class BeltRenderer extends SafeTileEntityRenderer { .add(0, verticalMovement, 0); boolean onSlope = slope != BeltSlope.HORIZONTAL && MathHelper.clamp(offset, .5f, te.beltLength - .5f) == offset; - boolean tiltForward = (slope == BeltSlope.DOWNWARD ^ te.getBeltFacing() - .getAxisDirection() == AxisDirection.POSITIVE) == (te.getBeltFacing() - .getAxis() == Axis.Z); + boolean tiltForward = (slope == BeltSlope.DOWNWARD ^ beltFacing + .getAxisDirection() == AxisDirection.POSITIVE) == (beltFacing + .getAxis() == Axis.Z); float slopeAngle = onSlope ? tiltForward ? -45 : 45 : 0; ms.translate(offsetVec.x, offsetVec.y, offsetVec.z); - boolean alongX = te.getBeltFacing() - .rotateY() - .getAxis() == Axis.X; + boolean alongX = beltFacing + .rotateY() + .getAxis() == Axis.X; if (!alongX) sideOffset *= -1; ms.translate(alongX ? sideOffset : 0, 0, alongX ? 0 : sideOffset); diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java index 84a60d265..a8c45f527 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltTileEntity.java @@ -63,8 +63,8 @@ public class BeltTileEntity extends KineticTileEntity { public CompoundNBT trackerUpdateTag; // client - public byte blockLight; - public byte skyLight; + public byte blockLight = -1; + public byte skyLight = -1; public static enum CasingType { NONE, ANDESITE, BRASS; @@ -137,11 +137,17 @@ public class BeltTileEntity extends KineticTileEntity { return super.calculateStressApplied(); } + private AxisAlignedBB cachedBoundingBox; @Override public AxisAlignedBB getRenderBoundingBox() { - if (!isController()) - return super.getRenderBoundingBox(); - return super.getRenderBoundingBox().grow(beltLength + 1); + if (cachedBoundingBox == null) { + if (!isController()) + cachedBoundingBox = super.getRenderBoundingBox(); + else + cachedBoundingBox = super.getRenderBoundingBox().grow(beltLength + 1); + } + + return cachedBoundingBox; } protected void initializeItemHandler() { @@ -261,6 +267,7 @@ public class BeltTileEntity extends KineticTileEntity { public void setController(BlockPos controller) { this.controller = controller; + cachedBoundingBox = null; } public BlockPos getController() { diff --git a/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperItemRenderer.java b/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperItemRenderer.java index 8414e43c8..5be2fb467 100644 --- a/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperItemRenderer.java +++ b/src/main/java/com/simibubi/create/content/curiosities/tools/SandPaperItemRenderer.java @@ -48,7 +48,7 @@ public class SandPaperItemRenderer extends ItemStackTileEntityRenderer { // Reverse bobbing float time = (float) (!jeiMode ? player.getItemInUseCount() - : (-AnimationTickHolder.ticks) % stack.getUseDuration()) - partialTicks + 1.0F; + : (-AnimationTickHolder.getTicks()) % stack.getUseDuration()) - partialTicks + 1.0F; if (time / (float) stack.getUseDuration() < 0.8F) { float bobbing = -MathHelper.abs(MathHelper.cos(time / 4.0F * (float) Math.PI) * 0.1F); diff --git a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java index 3e38b8abb..6d005cebc 100644 --- a/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java +++ b/src/main/java/com/simibubi/create/content/logistics/block/mechanicalArm/ArmRenderer.java @@ -6,12 +6,11 @@ import com.simibubi.create.AllBlockPartials; import com.simibubi.create.content.contraptions.base.KineticTileEntity; import com.simibubi.create.content.contraptions.base.KineticTileEntityRenderer; import com.simibubi.create.content.logistics.block.mechanicalArm.ArmTileEntity.Phase; +import com.simibubi.create.foundation.render.SuperByteBuffer; import com.simibubi.create.foundation.utility.AnimationTickHolder; import com.simibubi.create.foundation.utility.ColorHelper; import com.simibubi.create.foundation.utility.Iterate; import com.simibubi.create.foundation.utility.MatrixStacker; -import com.simibubi.create.foundation.render.SuperByteBuffer; - import net.minecraft.block.BlockState; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; @@ -56,7 +55,7 @@ public class ArmRenderer extends KineticTileEntityRenderer { lowerArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 4) + 1) / 2, -45, 15); upperArmAngle = MathHelper.lerp((MathHelper.sin(renderTick / 8) + 1) / 4, -45, 95); headAngle = -lowerArmAngle; - color = ColorHelper.rainbowColor(AnimationTickHolder.ticks * 100); + color = ColorHelper.rainbowColor(AnimationTickHolder.getTicks() * 100); } ms.push(); diff --git a/src/main/java/com/simibubi/create/events/ClientEvents.java b/src/main/java/com/simibubi/create/events/ClientEvents.java index fe626d735..734babaf8 100644 --- a/src/main/java/com/simibubi/create/events/ClientEvents.java +++ b/src/main/java/com/simibubi/create/events/ClientEvents.java @@ -50,7 +50,6 @@ import net.minecraftforge.client.event.EntityViewRenderEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent; import net.minecraftforge.client.event.RenderGameOverlayEvent.ElementType; import net.minecraftforge.client.event.RenderWorldLastEvent; -import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.TickEvent.ClientTickEvent; import net.minecraftforge.event.TickEvent.Phase; import net.minecraftforge.event.TickEvent.RenderTickEvent; @@ -114,13 +113,13 @@ public class ClientEvents { @SubscribeEvent public static void onLoadWorld(WorldEvent.Load event) { CreateClient.invalidateRenderers(); - AnimationTickHolder.ticks = 0; + AnimationTickHolder.reset(); } @SubscribeEvent public static void onUnloadWorld(WorldEvent.Unload event) { CreateClient.invalidateRenderers(); - AnimationTickHolder.ticks = 0; + AnimationTickHolder.reset(); } @SubscribeEvent diff --git a/src/main/java/com/simibubi/create/foundation/config/CClient.java b/src/main/java/com/simibubi/create/foundation/config/CClient.java index a1f3fbc13..e1043bca0 100644 --- a/src/main/java/com/simibubi/create/foundation/config/CClient.java +++ b/src/main/java/com/simibubi/create/foundation/config/CClient.java @@ -40,6 +40,12 @@ public class CClient extends ConfigBase { public Boolean get() { return super.get() && Backend.canUse(); } + + @Override + public void set(Boolean value) { + super.set(value); + Backend.enabled = get(); + } } } diff --git a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java index 208e1474b..f1265e932 100644 --- a/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java +++ b/src/main/java/com/simibubi/create/foundation/render/FastRenderDispatcher.java @@ -3,7 +3,6 @@ package com.simibubi.create.foundation.render; import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.systems.RenderSystem; import com.simibubi.create.CreateClient; -import com.simibubi.create.foundation.config.AllConfigs; import com.simibubi.create.foundation.render.contraption.ContraptionRenderDispatcher; import com.simibubi.create.foundation.render.gl.backend.Backend; import com.simibubi.create.foundation.render.gl.backend.OptifineHandler; @@ -59,7 +58,7 @@ public class FastRenderDispatcher { } public static boolean available() { - return AllConfigs.CLIENT.experimentalRendering.get(); + return Backend.enabled; } public static void refresh() { diff --git a/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java b/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java index bdd6c9ae1..40fcee652 100644 --- a/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java +++ b/src/main/java/com/simibubi/create/foundation/render/SuperByteBuffer.java @@ -1,24 +1,21 @@ package com.simibubi.create.foundation.render; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.util.function.Consumer; - import com.mojang.blaze3d.matrix.MatrixStack; import com.mojang.blaze3d.vertex.IVertexBuilder; import com.simibubi.create.foundation.block.render.SpriteShiftEntry; - import it.unimi.dsi.fastutil.longs.Long2DoubleMap; import it.unimi.dsi.fastutil.longs.Long2DoubleOpenHashMap; import net.minecraft.client.Minecraft; -import net.minecraft.client.renderer.BufferBuilder; -import net.minecraft.client.renderer.Matrix4f; -import net.minecraft.client.renderer.Vector4f; +import net.minecraft.client.renderer.*; import net.minecraft.client.renderer.texture.TextureAtlasSprite; import net.minecraft.util.Direction; import net.minecraft.util.math.BlockPos; import net.minecraft.world.LightType; import net.minecraft.world.World; +import net.minecraftforge.client.model.pipeline.LightUtil; + +import java.nio.Buffer; +import java.nio.ByteBuffer; public class SuperByteBuffer extends TemplateBuffer { @@ -60,6 +57,7 @@ public class SuperByteBuffer extends TemplateBuffer { private static final Long2DoubleMap skyLightCache = new Long2DoubleOpenHashMap(); private static final Long2DoubleMap blockLightCache = new Long2DoubleOpenHashMap(); Vector4f pos = new Vector4f(); + Vector3f normal = new Vector3f(); Vector4f lightPos = new Vector4f(); public void renderInto(MatrixStack input, IVertexBuilder builder) { @@ -68,12 +66,18 @@ public class SuperByteBuffer extends TemplateBuffer { return; ((Buffer) buffer).rewind(); - Matrix4f t = input.peek() - .getModel() - .copy(); + Matrix3f normalMat = transforms.peek() + .getNormal() + .copy(); + //normalMat.multiply(transforms.peek().getNormal()); + + Matrix4f modelMat = input.peek() + .getModel() + .copy(); + Matrix4f localTransforms = transforms.peek() - .getModel(); - t.multiply(localTransforms); + .getModel(); + modelMat.multiply(localTransforms); if (shouldLight && lightTransform != null) { skyLightCache.clear(); @@ -90,16 +94,33 @@ public class SuperByteBuffer extends TemplateBuffer { byte g = getG(buffer, i); byte b = getB(buffer, i); byte a = getA(buffer, i); + float normalX = getNX(buffer, i) / 127f; + float normalY = getNY(buffer, i) / 127f; + float normalZ = getNZ(buffer, i) / 127f; + + float staticDiffuse = LightUtil.diffuseLight(normalX, normalY, normalZ); + normal.set(normalX, normalY, normalZ); + normal.transform(normalMat); + float instanceDiffuse = LightUtil.diffuseLight(normal.getX(), normal.getY(), normal.getZ()); pos.set(x, y, z, 1F); - pos.transform(t); + pos.transform(modelMat); builder.vertex(pos.getX(), pos.getY(), pos.getZ()); + //builder.color((byte) Math.max(0, normal.getX() * 255), (byte) Math.max(0, normal.getY() * 255), (byte) Math.max(0, normal.getZ() * 255), a); if (shouldColor) { - float lum = (r < 0 ? 255 + r : r) / 256f; - builder.color((int) (this.r * lum), (int) (this.g * lum), (int) (this.b * lum), this.a); - } else - builder.color(r, g, b, a); + //float lum = (r < 0 ? 255 + r : r) / 256f; + int colorR = Math.min(255, (int) (((float) this.r) * instanceDiffuse)); + int colorG = Math.min(255, (int) (((float) this.g) * instanceDiffuse)); + int colorB = Math.min(255, (int) (((float) this.b) * instanceDiffuse)); + builder.color(colorR, colorG, colorB, this.a); + } else { + float diffuseMult = instanceDiffuse / staticDiffuse; + int colorR = Math.min(255, (int) (((float) Byte.toUnsignedInt(r)) * diffuseMult)); + int colorG = Math.min(255, (int) (((float) Byte.toUnsignedInt(g)) * diffuseMult)); + int colorB = Math.min(255, (int) (((float) Byte.toUnsignedInt(b)) * diffuseMult)); + builder.color(colorR, colorG, colorB, a); + } float u = getU(buffer, i); float v = getV(buffer, i); @@ -121,7 +142,7 @@ public class SuperByteBuffer extends TemplateBuffer { } else builder.light(getLight(buffer, i)); - builder.normal(getNX(buffer, i), getNY(buffer, i), getNZ(buffer, i)) + builder.normal(normal.getX(), normal.getY(), normal.getZ()) .endVertex(); } diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/BasicProgram.java b/src/main/java/com/simibubi/create/foundation/render/gl/BasicProgram.java index f00c9b443..b39fff2b7 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/BasicProgram.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/BasicProgram.java @@ -36,7 +36,7 @@ public class BasicProgram extends GlProgram { public void bind(Matrix4f viewProjection, int debugMode) { super.bind(); - GL20.glUniform1i(uTicks, AnimationTickHolder.ticks); + GL20.glUniform1i(uTicks, AnimationTickHolder.getTicks()); GL20.glUniform1f(uTime, AnimationTickHolder.getRenderTick()); uploadMatrixUniform(uViewProjection, viewProjection); GL20.glUniform1i(uDebug, debugMode); diff --git a/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java b/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java index 96fff17a3..4e47f8429 100644 --- a/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java +++ b/src/main/java/com/simibubi/create/foundation/render/gl/backend/Backend.java @@ -1,6 +1,10 @@ package com.simibubi.create.foundation.render.gl.backend; -import com.simibubi.create.foundation.render.gl.shader.*; +import com.simibubi.create.foundation.config.AllConfigs; +import com.simibubi.create.foundation.render.gl.shader.GlProgram; +import com.simibubi.create.foundation.render.gl.shader.GlShader; +import com.simibubi.create.foundation.render.gl.shader.ProgramSpec; +import com.simibubi.create.foundation.render.gl.shader.ShaderType; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.TextureUtil; import net.minecraft.resources.IReloadableResourceManager; @@ -35,6 +39,8 @@ public class Backend { private static final Map> registry = new HashMap<>(); private static final Map, GlProgram> programs = new HashMap<>(); + public static boolean enabled; + public static GLCapabilities capabilities; private static SystemCapability capability; private static MapBuffer mapBuffer; @@ -143,6 +149,8 @@ public class Backend { } else { capability = SystemCapability.INCAPABLE; } + + enabled = AllConfigs.CLIENT.experimentalRendering.get(); } private static

> void loadProgram(IResourceManager manager, S programSpec) { diff --git a/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java index 6037e97fd..0ebf612f3 100644 --- a/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java +++ b/src/main/java/com/simibubi/create/foundation/render/instancing/InstancedTileRenderer.java @@ -93,7 +93,7 @@ public abstract class InstancedTileRenderer

{ public void clean() { // Clean up twice a second. This doesn't have to happen every tick, // but this does need to be run to ensure we don't miss anything. - if (AnimationTickHolder.ticks % 10 == 0) { + if (AnimationTickHolder.getTicks() % 10 == 0) { instances.keySet().stream().filter(TileEntity::isRemoved).forEach(instances::remove); } } diff --git a/src/main/java/com/simibubi/create/foundation/utility/AnimationTickHolder.java b/src/main/java/com/simibubi/create/foundation/utility/AnimationTickHolder.java index f8c654658..4b8f410c5 100644 --- a/src/main/java/com/simibubi/create/foundation/utility/AnimationTickHolder.java +++ b/src/main/java/com/simibubi/create/foundation/utility/AnimationTickHolder.java @@ -4,14 +4,20 @@ import net.minecraft.client.Minecraft; public class AnimationTickHolder { - public static int ticks; + private static int ticks; + + public static void reset() { + ticks = 0; + } public static void tick() { - if (!Minecraft.getInstance().isGamePaused()) ticks++; + if (!Minecraft.getInstance().isGamePaused()) { + ticks = (ticks + 1) % 1_728_000; // wrap around every 24 hours so we maintain enough floating point precision + } } public static float getRenderTick() { - return ticks + getPartialTicks(); + return getTicks() + getPartialTicks(); } public static float getPartialTicks() { @@ -19,4 +25,7 @@ public class AnimationTickHolder { return (mc.isGamePaused() ? mc.renderPartialTicksPaused : mc.getRenderPartialTicks()); } + public static int getTicks() { + return ticks; + } }