diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java index 40ae4a7b0..b4dab5758 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/Contraption.java @@ -1094,7 +1094,7 @@ public abstract class Contraption { GridAlignedBB betterBounds = GridAlignedBB.ofRadius(radius); - GridAlignedBB contraptionBounds = GridAlignedBB.fromAABB(bounds); + GridAlignedBB contraptionBounds = GridAlignedBB.from(bounds); if (axis == Direction.Axis.X) { betterBounds.maxX = contraptionBounds.maxX; betterBounds.minX = contraptionBounds.minX; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java index 3ab1805e5..697fb4a63 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/ContraptionLighter.java @@ -40,13 +40,15 @@ public abstract class ContraptionLighter implements Light public abstract GridAlignedBB getContraptionBounds(); @Override - public void onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) { + public boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) { lightVolume.notifyLightUpdate(world, type, changed); + return false; } @Override - public void onLightPacket(ILightReader world, int chunkX, int chunkZ) { + public boolean onLightPacket(ILightReader world, int chunkX, int chunkZ) { lightVolume.notifyLightPacket(world, chunkX, chunkZ); + return false; } protected void startListening() { diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java index 5678f103c..c20a34145 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/NonStationaryLighter.java @@ -32,7 +32,7 @@ public class NonStationaryLighter extends ContraptionLigh @Override public GridAlignedBB getContraptionBounds() { - GridAlignedBB bb = GridAlignedBB.fromAABB(contraption.bounds); + GridAlignedBB bb = GridAlignedBB.from(contraption.bounds); bb.translate(contraption.entity.getPosition()); diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/AnchoredLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/AnchoredLighter.java index 09cfa2a39..b5ed7ee45 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/AnchoredLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/bearing/AnchoredLighter.java @@ -12,7 +12,7 @@ public class AnchoredLighter extends ContraptionLighter { @Override public GridAlignedBB getContraptionBounds() { - GridAlignedBB bb = GridAlignedBB.fromAABB(contraption.bounds); + GridAlignedBB bb = GridAlignedBB.from(contraption.bounds); bb.translate(contraption.anchor); return bb; } diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonLighter.java index 1c8ffa5ed..bbc228cb6 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/piston/PistonLighter.java @@ -12,7 +12,7 @@ public class PistonLighter extends ContraptionLighter { @Override public GridAlignedBB getContraptionBounds() { - GridAlignedBB bounds = GridAlignedBB.fromAABB(contraption.bounds); + GridAlignedBB bounds = GridAlignedBB.from(contraption.bounds); bounds.translate(contraption.anchor); int length = contraption.extensionLength; diff --git a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java index 4714a30e3..426a49a4e 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java +++ b/src/main/java/com/simibubi/create/content/contraptions/components/structureMovement/pulley/PulleyLighter.java @@ -15,7 +15,7 @@ public class PulleyLighter extends ContraptionLighter { @Override public GridAlignedBB getContraptionBounds() { - GridAlignedBB bounds = GridAlignedBB.fromAABB(contraption.bounds); + GridAlignedBB bounds = GridAlignedBB.from(contraption.bounds); World world = contraption.entity.world; diff --git a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java index c8b4c582e..e2cac72ac 100644 --- a/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java +++ b/src/main/java/com/simibubi/create/content/contraptions/relays/belt/BeltRenderer.java @@ -294,10 +294,10 @@ public class BeltRenderer extends SafeTileEntityRenderer { } protected int getPackedLight(BeltTileEntity controller, float beltPos) { - BeltTileEntity belt = BeltHelper.getBeltForOffset(controller, beltPos); + int segment = (int) Math.floor(beltPos) * 2; - if (belt == null) return 0; + if (controller.light == null || segment >= controller.light.length) return 0; - return (belt.skyLight << 20) | (belt.blockLight << 4); + return (controller.light[segment + 1] << 20) | (controller.light[segment] << 4); } } 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 4c16a9d29..42efd9396 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 @@ -23,7 +23,9 @@ import com.simibubi.create.content.contraptions.relays.belt.transport.ItemHandle import com.simibubi.create.content.contraptions.relays.belt.transport.TransportedItemStack; import com.simibubi.create.content.logistics.block.belts.tunnel.BrassTunnelTileEntity; import com.simibubi.create.foundation.render.backend.FastRenderDispatcher; -import com.simibubi.create.foundation.render.backend.light.ILightListener; +import com.simibubi.create.foundation.render.backend.light.GridAlignedBB; +import com.simibubi.create.foundation.render.backend.light.LightUpdateListener; +import com.simibubi.create.foundation.render.backend.light.LightUpdater; import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.DirectBeltInputBehaviour; import com.simibubi.create.foundation.tileEntity.behaviour.belt.TransportedItemStackHandlerBehaviour; @@ -46,6 +48,7 @@ import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3i; +import net.minecraft.world.ILightReader; import net.minecraft.world.LightType; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.model.data.IModelData; @@ -57,7 +60,7 @@ import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.items.CapabilityItemHandler; import net.minecraftforge.items.IItemHandler; -public class BeltTileEntity extends KineticTileEntity implements ILightListener { +public class BeltTileEntity extends KineticTileEntity implements LightUpdateListener { public Map passengers; public Optional color; @@ -73,8 +76,7 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener public CompoundNBT trackerUpdateTag; // client - public byte blockLight = -1; - public byte skyLight = -1; + public byte[] light; public static enum CasingType { NONE, ANDESITE, BRASS; @@ -109,8 +111,9 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener initializeItemHandler(); - if (blockLight == -1) - updateLight(); + if (light == null && isController()) + LightUpdater.getInstance().startListening(getBeltVolume(), this); + initializeLight(); // Move Items if (!isController()) @@ -513,23 +516,68 @@ public class BeltTileEntity extends KineticTileEntity implements ILightListener return 0; } - @Override - public void onChunkLightUpdate() { - updateLight(); - } - @Override public boolean shouldRenderAsTE() { return isController(); } - private void updateLight() { - if (world != null) { - skyLight = (byte) world.getLightLevel(LightType.SKY, pos); - blockLight = (byte) world.getLightLevel(LightType.BLOCK, pos); - } else { - skyLight = -1; - blockLight = -1; + @Override + public boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed) { + if (this.removed) { + return true; + } + + GridAlignedBB beltVolume = getBeltVolume(); + + if (beltVolume.intersects(changed)) { + GridAlignedBB section = changed.intersect(beltVolume); + + if (type == LightType.BLOCK) + section.forEachContained(this::updateBlockLight); + + if (type == LightType.SKY) + section.forEachContained(this::updateSkyLight); + } + + return false; + } + + private GridAlignedBB getBeltVolume() { + BlockPos endPos = controller.offset(getBeltFacing(), beltLength - 1); + + return GridAlignedBB.from(pos, endPos); + } + + private void updateBlockLight(int x, int y, int z) { + int segment = posToSegment(x, y, z) * 2; + + light[segment] = (byte) world.getLightLevel(LightType.BLOCK, new BlockPos(x, y, z)); + } + + private void updateSkyLight(int x, int y, int z) { + int segment = posToSegment(x, y, z) * 2; + + light[segment + 1] = (byte) world.getLightLevel(LightType.SKY, new BlockPos(x, y, z)); + } + + private int posToSegment(int x, int y, int z) { + int dX = Math.abs(controller.getX() - x); + int dY = Math.abs(controller.getY() - y); + int dZ = Math.abs(controller.getZ() - z); + return dY + dX + dZ; + } + + private void initializeLight() { + light = new byte[beltLength * 2]; + + Direction facing = getBeltFacing(); + BlockPos.Mutable pos = new BlockPos.Mutable(controller); + for (int i = 0; i < beltLength; i++) { + int segment = 2 * i; + light[segment] = (byte) world.getLightLevel(LightType.BLOCK, pos); + light[segment + 1] = (byte) world.getLightLevel(LightType.SKY, pos); + + pos.move(facing); } } } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java index 81501b16c..3d07bd0bf 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/LightUpdateMixin.java @@ -10,7 +10,6 @@ import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; -import com.simibubi.create.foundation.render.backend.light.ILightListener; import com.simibubi.create.foundation.render.backend.light.LightUpdater; import net.minecraft.client.multiplayer.ClientChunkProvider; @@ -49,9 +48,6 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider { .map(Map.Entry::getValue) .forEach(tile -> { CreateClient.kineticRenderer.get(world).onLightUpdate(tile); - - if (tile instanceof ILightListener) - ((ILightListener) tile).onChunkLightUpdate(); }); } diff --git a/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java b/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java index 9e775c094..e3eda853e 100644 --- a/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java +++ b/src/main/java/com/simibubi/create/foundation/mixin/NetworkLightUpdateMixin.java @@ -3,7 +3,6 @@ package com.simibubi.create.foundation.mixin; import com.simibubi.create.CreateClient; import com.simibubi.create.content.contraptions.components.structureMovement.render.ContraptionRenderDispatcher; import com.simibubi.create.foundation.render.backend.RenderWork; -import com.simibubi.create.foundation.render.backend.light.ILightListener; import com.simibubi.create.foundation.render.backend.light.LightUpdater; import net.minecraft.client.Minecraft; @@ -39,9 +38,6 @@ public class NetworkLightUpdateMixin { .values() .forEach(tile -> { CreateClient.kineticRenderer.get(world).onLightUpdate(tile); - - if (tile instanceof ILightListener) - ((ILightListener) tile).onChunkLightUpdate(); }); } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java index 5ee051229..6d14579f5 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/GridAlignedBB.java @@ -6,6 +6,7 @@ import com.simibubi.create.foundation.render.backend.RenderUtil; import net.minecraft.util.Direction; import net.minecraft.util.math.AxisAlignedBB; +import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.SectionPos; import net.minecraft.util.math.Vec3i; @@ -34,7 +35,7 @@ public class GridAlignedBB { return new GridAlignedBB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); } - public static GridAlignedBB fromAABB(AxisAlignedBB aabb) { + public static GridAlignedBB from(AxisAlignedBB aabb) { int minX = (int) Math.floor(aabb.minX); int minY = (int) Math.floor(aabb.minY); int minZ = (int) Math.floor(aabb.minZ); @@ -44,7 +45,7 @@ public class GridAlignedBB { return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ); } - public static GridAlignedBB fromSection(SectionPos pos) { + public static GridAlignedBB from(SectionPos pos) { return new GridAlignedBB(pos.getWorldStartX(), pos.getWorldStartY(), pos.getWorldStartZ(), @@ -53,7 +54,16 @@ public class GridAlignedBB { pos.getWorldEndZ() + 1); } - public static GridAlignedBB fromChunk(int sectionX, int sectionZ) { + public static GridAlignedBB from(BlockPos start, BlockPos end) { + return new GridAlignedBB(start.getX(), + start.getY(), + start.getZ(), + end.getX() + 1, + end.getY() + 1, + end.getZ() + 1); + } + + public static GridAlignedBB from(int sectionX, int sectionZ) { int startX = sectionX << 4; int startZ = sectionZ << 4; return new GridAlignedBB(startX, diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/ILightListener.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/ILightListener.java deleted file mode 100644 index 5fd2ff8bd..000000000 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/ILightListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.simibubi.create.foundation.render.backend.light; - -public interface ILightListener { - void onChunkLightUpdate(); -} diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java index 48de4e397..eacb5aa59 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdateListener.java @@ -11,16 +11,22 @@ public interface LightUpdateListener { /** * Called when a light updates in a chunk the implementor cares about. + * + * @return true if this object is no longer valid and should not receive any more updates. */ - void onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed); + boolean onLightUpdate(ILightReader world, LightType type, GridAlignedBB changed); /** * Called when the server sends light data to the client. + * + * @return true if this object is no longer valid and should not receive any more updates. */ - default void onLightPacket(ILightReader world, int chunkX, int chunkZ) { - GridAlignedBB changedVolume = GridAlignedBB.fromChunk(chunkX, chunkZ); + default boolean onLightPacket(ILightReader world, int chunkX, int chunkZ) { + GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ); - onLightUpdate(world, LightType.BLOCK, changedVolume); - onLightUpdate(world, LightType.SKY, changedVolume); + if (onLightUpdate(world, LightType.BLOCK, changedVolume)) + return true; + + return onLightUpdate(world, LightType.SKY, changedVolume); } } diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java index dc6a7ca7b..634d221b1 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightUpdater.java @@ -114,12 +114,9 @@ public class LightUpdater { if (set == null || set.isEmpty()) return; - GridAlignedBB chunkBox = GridAlignedBB.fromSection(SectionPos.from(sectionPos)); - - for (LightUpdateListener listener : set) { - listener.onLightUpdate(world, type, chunkBox.copy()); - } + GridAlignedBB chunkBox = GridAlignedBB.from(SectionPos.from(sectionPos)); + set.removeIf(listener -> listener.onLightUpdate(world, type, chunkBox.copy())); } /** @@ -136,10 +133,7 @@ public class LightUpdater { if (set == null || set.isEmpty()) return; - for (LightUpdateListener listener : set) { - listener.onLightPacket(world, chunkX, chunkZ); - } - + set.removeIf(listener -> listener.onLightPacket(world, chunkX, chunkZ)); } private LongRBTreeSet clearChunks(LightUpdateListener listener) { diff --git a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java index 7c80e0765..c61aafc0f 100644 --- a/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java +++ b/src/main/java/com/simibubi/create/foundation/render/backend/light/LightVolume.java @@ -14,7 +14,6 @@ import com.simibubi.create.foundation.render.backend.RenderWork; import com.simibubi.create.foundation.render.backend.gl.GlTexture; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.SectionPos; import net.minecraft.world.ILightReader; import net.minecraft.world.LightType; @@ -138,7 +137,7 @@ public class LightVolume { public void notifyLightPacket(ILightReader world, int chunkX, int chunkZ) { if (removed) return; - GridAlignedBB changedVolume = GridAlignedBB.fromChunk(chunkX, chunkZ); + GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ); if (!changedVolume.intersects(sampleVolume)) return; changedVolume.intersectAssign(sampleVolume); // compute the region contained by us that has dirty lighting data.