diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java index bb4750280..e7c71e2e7 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterRenderer.java @@ -1,21 +1,18 @@ package com.simibubi.create.content.contraptions.processing; +import java.util.HashMap; + import com.mojang.blaze3d.matrix.MatrixStack; import com.simibubi.create.AllBlockPartials; import com.simibubi.create.foundation.tileEntity.renderer.SafeTileEntityRenderer; import com.simibubi.create.foundation.utility.SuperByteBuffer; -import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.IRenderTypeBuffer; import net.minecraft.client.renderer.RenderType; -import net.minecraft.client.renderer.Vector3f; import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; import net.minecraft.util.Direction; -import java.util.HashMap; - public class HeaterRenderer extends SafeTileEntityRenderer { - private static final Minecraft INSTANCE = Minecraft.getInstance(); private static final HashMap blazeModelMap = new HashMap<>(); public HeaterRenderer(TileEntityRendererDispatcher dispatcher) { @@ -30,23 +27,9 @@ public class HeaterRenderer extends SafeTileEntityRenderer { int light, int overlay) { AllBlockPartials blazeModel = blazeModelMap.getOrDefault(te.getHeatLevel(), AllBlockPartials.BLAZE_HEATER_BLAZE_ONE); - - float angle; - if (INSTANCE.player == null) { - angle = 0; - } else { - Vector3f difference = new Vector3f(INSTANCE.player.getPositionVector() - .subtract(te.getPos() - .getX() + 0.5, 0, - te.getPos() - .getZ() + 0.5) - .mul(1, 0, 1)); - difference.normalize(); - angle = (float) ((difference.getX() < 0 ? 1 : -1) * Math.acos(Direction.NORTH.getUnitVector() - .dot(difference))); - } + SuperByteBuffer blazeBuffer = blazeModel.renderOn(te.getBlockState()); - blazeBuffer.rotateCentered(Direction.UP, angle); - blazeBuffer.renderInto(ms, buffer.getBuffer(RenderType.getSolid())); + blazeBuffer.rotateCentered(Direction.UP, (float) Math.toRadians(-te.rot + (te.speed * partialTicks))); + blazeBuffer.light(0xF000F0).renderInto(ms, buffer.getBuffer(RenderType.getSolid())); } } diff --git a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java index cae5645e7..0b813f46e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java +++ b/src/main/java/com/simibubi/create/content/contraptions/processing/HeaterTileEntity.java @@ -10,12 +10,15 @@ import com.simibubi.create.content.contraptions.particle.CubeParticleData; import com.simibubi.create.foundation.tileEntity.SmartTileEntity; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.utility.ColorHelper; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.projectile.EggEntity; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundNBT; -import net.minecraft.tileentity.TileEntity; import net.minecraft.particles.IParticleData; +import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntityType; import net.minecraft.util.SoundCategory; import net.minecraft.util.math.BlockPos; @@ -42,6 +45,9 @@ public class HeaterTileEntity extends SmartTileEntity { private int remainingBurnTime; private FuelType activeFuel; + + // Rendering state + float rot, speed; public HeaterTileEntity(TileEntityType tileEntityTypeIn) { super(tileEntityTypeIn); @@ -53,6 +59,9 @@ public class HeaterTileEntity extends SmartTileEntity { @Override public void tick() { super.tick(); + if (world.isRemote) { + tickRotation(); + } spawnParticles(getHeatLevel()); @@ -71,6 +80,68 @@ public class HeaterTileEntity extends SmartTileEntity { } markDirty(); } + + private static final float MAX_ROT_SPEED = 5; + private static final float ROT_DAMPING = 15; + + private void tickRotation() { + ClientPlayerEntity player = Minecraft.getInstance().player; + Angle target; + if (player == null) { + target = new Angle(360, 0); + } else { + double dx = player.getX() - (getPos().getX() + 0.5); + double dz = player.getZ() - (getPos().getZ() + 0.5); + target = new Angle(360, (float) (MathHelper.atan2(dz, dx) * 180.0 / Math.PI + 90)); + } + + Angle current = new Angle(360, rot); + float diff = new Angle(180, current.get() - target.get()).get(); + if (diff > 0.1 || diff < -0.1) { + // Inverse function https://www.desmos.com/calculator/kiaberb6sf + speed = MAX_ROT_SPEED + (-MAX_ROT_SPEED / ((Math.abs(diff) / ROT_DAMPING) + 1)); + if (diff > 0) { + current.add(-Math.min(diff, speed)); + speed = Math.min(diff, speed); + } else { + current.add(Math.min(-diff, speed)); + speed = Math.min(-diff, -speed); + } + } else { + speed = 0; + } + + rot = current.get(); + } + + // From EnderIO with <3 + private static class Angle { + private final float offset; + private float a; + + Angle(float offset, float a) { + this.offset = offset; + set(a); + } + + void set(float a) { + while (a >= offset) { + a -= 360; + } + while (a < (offset - 360)) { + a += 360; + } + this.a = a; + } + + void add(float b) { + set(a + b); + } + + float get() { + return a; + } + } @Override public void lazyTick() {