Optimize BasinRenderer

* Do not render items and fluids if basin is higher than player
* Do not get ChunkAccess if there is no visualizedOutputItems
This commit is contained in:
MoePus 2024-11-04 23:44:33 +09:00
parent d48a504486
commit 5544a69c77

View file

@ -5,6 +5,7 @@ import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTank
import com.simibubi.create.foundation.blockEntity.behaviour.fluid.SmartFluidTankBehaviour.TankSegment;
import com.simibubi.create.foundation.blockEntity.renderer.SmartBlockEntityRenderer;
import com.simibubi.create.foundation.fluid.FluidRenderer;
import com.simibubi.create.foundation.ponder.PonderWorld;
import com.simibubi.create.foundation.utility.AngleHelper;
import com.simibubi.create.foundation.utility.AnimationTickHolder;
import com.simibubi.create.foundation.utility.IntAttached;
@ -19,6 +20,7 @@ import net.minecraft.core.Direction;
import net.minecraft.core.Direction.Axis;
import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.item.ItemDisplayContext;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.state.BlockState;
@ -38,66 +40,14 @@ public class BasinRenderer extends SmartBlockEntityRenderer<BasinBlockEntity> {
int light, int overlay) {
super.renderSafe(basin, partialTicks, ms, buffer, light, overlay);
float fluidLevel = renderFluids(basin, partialTicks, ms, buffer, light, overlay);
float level = Mth.clamp(fluidLevel - .3f, .125f, .6f);
ms.pushPose();
BlockPos pos = basin.getBlockPos();
ms.translate(.5, .2f, .5);
TransformStack.of(ms)
.rotateYDegrees(basin.ingredientRotation.getValue(partialTicks));
RandomSource r = RandomSource.create(pos.hashCode());
Vec3 baseVector = new Vec3(.125, level, 0);
IItemHandlerModifiable inv = basin.itemCapability.orElse(new ItemStackHandler());
int itemCount = 0;
for (int slot = 0; slot < inv.getSlots(); slot++)
if (!inv.getStackInSlot(slot)
.isEmpty())
itemCount++;
if (itemCount == 1)
baseVector = new Vec3(0, level, 0);
float anglePartition = 360f / itemCount;
for (int slot = 0; slot < inv.getSlots(); slot++) {
ItemStack stack = inv.getStackInSlot(slot);
if (stack.isEmpty())
continue;
ms.pushPose();
if (fluidLevel > 0) {
ms.translate(0,
(Mth.sin(
AnimationTickHolder.getRenderTime(basin.getLevel()) / 12f + anglePartition * itemCount) + 1.5f)
* 1 / 32f,
0);
}
Vec3 itemPosition = VecHelper.rotate(baseVector, anglePartition * itemCount, Axis.Y);
ms.translate(itemPosition.x, itemPosition.y, itemPosition.z);
TransformStack.of(ms)
.rotateYDegrees(anglePartition * itemCount + 35)
.rotateXDegrees(65);
for (int i = 0; i <= stack.getCount() / 8; i++) {
ms.pushPose();
Vec3 vec = VecHelper.offsetRandomly(Vec3.ZERO, r, 1 / 16f);
ms.translate(vec.x, vec.y, vec.z);
renderItem(ms, buffer, light, overlay, stack);
ms.popPose();
}
ms.popPose();
itemCount--;
Entity camera = Minecraft.getInstance().cameraEntity;
if (basin.getLevel() instanceof PonderWorld || (camera != null && basin.getBlockPos().getY() - 1.0F <= camera.getY())) {
float fluidLevel = renderFluids(basin, partialTicks, ms, buffer, light, overlay);
renderInsideItems(basin, partialTicks, ms, buffer, light, overlay, fluidLevel);
}
ms.popPose();
if(basin.visualizedOutputItems.isEmpty())
return;
BlockState blockState = basin.getBlockState();
if (!(blockState.getBlock() instanceof BasinBlock))
return;
@ -181,6 +131,61 @@ public class BasinRenderer extends SmartBlockEntityRenderer<BasinBlockEntity> {
return yMax;
}
protected void renderInsideItems(BasinBlockEntity basin, float partialTicks, PoseStack ms, MultiBufferSource buffer,
int light, int overlay, float fluidLevel) {
IItemHandlerModifiable inv = basin.itemCapability.orElse(new ItemStackHandler());
int itemCount = 0;
for (int slot = 0; slot < inv.getSlots(); slot++)
if (!inv.getStackInSlot(slot).isEmpty())
itemCount++;
if (itemCount == 0)
return;
ms.pushPose();
ms.translate(.5, .2f, .5);
TransformStack.of(ms)
.rotateYDegrees(basin.ingredientRotation.getValue(partialTicks));
float level = Mth.clamp(fluidLevel - .3f, .125f, .6f);
Vec3 baseVector = new Vec3(itemCount == 1 ? 0 : .125, level, 0);
RandomSource r = RandomSource.create(basin.getBlockPos().hashCode());
float anglePartition = 360f / itemCount;
for (int slot = 0; slot < inv.getSlots(); slot++) {
ItemStack stack = inv.getStackInSlot(slot);
if (stack.isEmpty())
continue;
ms.pushPose();
if (fluidLevel > 0) {
float renderTime = AnimationTickHolder.getRenderTime(basin.getLevel());
ms.translate(0, (Mth.sin(renderTime / 12f + anglePartition * itemCount) + 1.5f) * 1 / 32f,
0);
}
Vec3 itemPosition = VecHelper.rotate(baseVector, anglePartition * itemCount, Axis.Y);
ms.translate(itemPosition.x, itemPosition.y, itemPosition.z);
TransformStack.of(ms)
.rotateYDegrees(anglePartition * itemCount + 35)
.rotateXDegrees(65);
for (int i = 0; i <= stack.getCount() / 8; i++) {
ms.pushPose();
Vec3 vec = VecHelper.offsetRandomly(Vec3.ZERO, r, 1 / 16f);
ms.translate(vec.x, vec.y, vec.z);
renderItem(ms, buffer, light, overlay, stack);
ms.popPose();
}
ms.popPose();
itemCount--;
}
ms.popPose();
}
@Override
public int getViewDistance() {
return 16;