diff --git a/src/main/java/com/jozufozu/flywheel/Flywheel.java b/src/main/java/com/jozufozu/flywheel/Flywheel.java index fb80e35c0..e44464612 100644 --- a/src/main/java/com/jozufozu/flywheel/Flywheel.java +++ b/src/main/java/com/jozufozu/flywheel/Flywheel.java @@ -4,6 +4,7 @@ import com.jozufozu.flywheel.config.FlwCommands; import com.jozufozu.flywheel.config.FlwConfig; import com.jozufozu.flywheel.config.FlwPackets; +import net.minecraft.util.ResourceLocation; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.DistExecutor; @@ -28,7 +29,11 @@ public class Flywheel { DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> FlywheelClient::clientInit); } - private void setup(final FMLCommonSetupEvent event) { + public static ResourceLocation rl(String path) { + return new ResourceLocation(ID, path); + } + + private void setup(final FMLCommonSetupEvent event) { FlwPackets.registerPackets(); } } diff --git a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java b/src/main/java/com/jozufozu/flywheel/FlywheelClient.java index 9cf2e6f79..8e08e111c 100644 --- a/src/main/java/com/jozufozu/flywheel/FlywheelClient.java +++ b/src/main/java/com/jozufozu/flywheel/FlywheelClient.java @@ -5,6 +5,7 @@ import com.jozufozu.flywheel.core.AtlasStitcher; import com.jozufozu.flywheel.core.Contexts; import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.PartialModel; +import com.jozufozu.flywheel.light.debug.DebugView; import com.jozufozu.flywheel.vanilla.VanillaInstances; import net.minecraftforge.eventbus.api.IEventBus; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java index 8fbfdc2ef..8c985b56b 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/AbstractInstance.java @@ -8,11 +8,10 @@ import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.core.materials.IFlatLight; import com.jozufozu.flywheel.light.GridAlignedBB; import com.jozufozu.flywheel.light.ILightUpdateListener; -import com.jozufozu.flywheel.light.LightUpdater; +import com.jozufozu.flywheel.light.LightProvider; import com.jozufozu.flywheel.light.ListenerStatus; import net.minecraft.util.math.BlockPos; -import net.minecraft.world.IBlockDisplayReader; import net.minecraft.world.LightType; import net.minecraft.world.World; @@ -23,7 +22,7 @@ import net.minecraft.world.World; public abstract class AbstractInstance implements IInstance, ILightUpdateListener { protected final MaterialManager materialManager; - protected final World world; + public final World world; public AbstractInstance(MaterialManager materialManager, World world) { this.materialManager = materialManager; @@ -74,7 +73,7 @@ public abstract class AbstractInstance implements IInstance, ILightUpdateListene } @Override - public void onLightUpdate(IBlockDisplayReader world, LightType type, GridAlignedBB changed) { + public void onLightUpdate(LightProvider world, LightType type, GridAlignedBB changed) { updateLight(); } diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java index 69f87bf1c..3e8d307c1 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java @@ -11,6 +11,7 @@ import javax.annotation.Nullable; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.material.MaterialManager; import com.jozufozu.flywheel.backend.material.MaterialManagerImpl; +import com.jozufozu.flywheel.light.LightUpdater; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.client.renderer.ActiveRenderInfo; @@ -285,7 +286,7 @@ public abstract class InstanceManager implements MaterialManagerImpl.OriginSh if (renderer != null) { renderer.updateLight(); - renderer.startListening(); + LightUpdater.get(renderer.world).addListener(renderer); instances.put(obj, renderer); if (renderer instanceof IDynamicInstance) dynamicInstances.put(obj, (IDynamicInstance) renderer); diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java index 5fbdcd6bd..840630b1e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java @@ -1,19 +1,18 @@ package com.jozufozu.flywheel.backend.instancing.entity; -import java.util.Arrays; -import java.util.stream.Stream; - import com.jozufozu.flywheel.backend.instancing.IDynamicInstance; import com.jozufozu.flywheel.backend.instancing.AbstractInstance; import com.jozufozu.flywheel.backend.instancing.ITickableInstance; import com.jozufozu.flywheel.backend.instancing.tile.TileInstanceManager; import com.jozufozu.flywheel.backend.material.MaterialManager; +import com.jozufozu.flywheel.light.GridAlignedBB; import com.jozufozu.flywheel.light.ILightUpdateListener; -import com.jozufozu.flywheel.light.ListenerStatus; -import com.jozufozu.flywheel.light.Volume; +import com.jozufozu.flywheel.light.IMovingListener; +import com.jozufozu.flywheel.light.LightProvider; import net.minecraft.entity.Entity; import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.vector.Vector3d; @@ -35,25 +34,33 @@ import net.minecraft.util.math.vector.Vector3i; * * @param The type of {@link Entity} your class is an instance of. */ -public abstract class EntityInstance extends AbstractInstance implements ILightUpdateListener { +public abstract class EntityInstance extends AbstractInstance implements ILightUpdateListener, IMovingListener { protected final E entity; + protected final GridAlignedBB bounds; public EntityInstance(MaterialManager materialManager, E entity) { super(materialManager, entity.level); this.entity = entity; - - startListening(); + bounds = GridAlignedBB.from(entity.getBoundingBox()); } @Override - public Volume.Box getVolume() { - return Volume.box(entity.getBoundingBox()); + public GridAlignedBB getVolume() { + return bounds; } @Override - public ListenerStatus status() { - return ListenerStatus.UPDATE; + public boolean update(LightProvider provider) { + AxisAlignedBB boundsNow = entity.getBoundingBox(); + + if (bounds.sameAs(boundsNow)) return false; + + bounds.assign(boundsNow); + + updateLight(); + + return true; } /** diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java index 876035a34..16fc5aede 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/tile/TileEntityInstance.java @@ -9,7 +9,6 @@ import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.materials.ModelData; import com.jozufozu.flywheel.core.materials.OrientedData; import com.jozufozu.flywheel.light.GridAlignedBB; -import com.jozufozu.flywheel.light.Volume; import net.minecraft.block.BlockState; import net.minecraft.tileentity.TileEntity; @@ -85,7 +84,7 @@ public abstract class TileEntityInstance extends AbstractI } @Override - public Volume.Block getVolume() { - return Volume.block(pos); + public GridAlignedBB getVolume() { + return GridAlignedBB.from(pos); } } diff --git a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java index 13a8ad429..869c52da4 100644 --- a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java +++ b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java @@ -11,7 +11,6 @@ import net.minecraft.client.world.ClientWorld; import net.minecraft.world.IWorld; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.client.event.RenderGameOverlayEvent; -import net.minecraftforge.client.event.RenderWorldLastEvent; import net.minecraftforge.event.TickEvent; import net.minecraftforge.event.world.WorldEvent; import net.minecraftforge.eventbus.api.SubscribeEvent; @@ -51,7 +50,7 @@ public class ForgeEvents { @SubscribeEvent public static void rwle(TickEvent.ClientTickEvent e) { if (e.phase == TickEvent.Phase.END && Backend.isGameActive()) - LightUpdater.getInstance().tick(); + LightUpdater.get(Minecraft.getInstance().level).tick(); } } diff --git a/src/main/java/com/jozufozu/flywheel/light/BasicProvider.java b/src/main/java/com/jozufozu/flywheel/light/BasicProvider.java new file mode 100644 index 000000000..ac3af492c --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/light/BasicProvider.java @@ -0,0 +1,30 @@ +package com.jozufozu.flywheel.light; + +import java.util.Map; +import java.util.WeakHashMap; + +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.IBlockDisplayReader; +import net.minecraft.world.LightType; + +public class BasicProvider implements LightProvider { + + private static final Map wrappers = new WeakHashMap<>(); + + public static BasicProvider get(IBlockDisplayReader world) { + return wrappers.computeIfAbsent(world, BasicProvider::new); + } + + private final BlockPos.Mutable pos = new BlockPos.Mutable(); + + private final IBlockDisplayReader reader; + + public BasicProvider(IBlockDisplayReader reader) { + this.reader = reader; + } + + @Override + public int getLight(LightType type, int x, int y, int z) { + return reader.getBrightness(type, pos.set(x, y, z)); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/light/GridAlignedBB.java b/src/main/java/com/jozufozu/flywheel/light/GridAlignedBB.java index cdecc44af..706359d58 100644 --- a/src/main/java/com/jozufozu/flywheel/light/GridAlignedBB.java +++ b/src/main/java/com/jozufozu/flywheel/light/GridAlignedBB.java @@ -75,6 +75,15 @@ public class GridAlignedBB { return minX == other.minX && minY == other.minY && minZ == other.minZ && maxX == other.maxX && maxY == other.maxY && maxZ == other.maxZ; } + public boolean sameAs(AxisAlignedBB other) { + return minX == Math.floor(other.minX) + && minY == Math.floor(other.minY) + && minZ == Math.floor(other.minZ) + && maxX == Math.ceil(other.maxX) + && maxY == Math.ceil(other.maxY) + && maxZ == Math.ceil(other.maxZ); + } + public void fixMinMax() { int minX = Math.min(this.minX, this.maxX); int minY = Math.min(this.minY, this.maxY); @@ -245,6 +254,24 @@ public class GridAlignedBB { this.maxZ = Math.max(this.maxZ, (int) Math.ceil(other.maxZ)); } + public void assign(AxisAlignedBB other) { + this.minX = (int) Math.floor(other.minX); + this.minY = (int) Math.floor(other.minY); + this.minZ = (int) Math.floor(other.minZ); + this.maxX = (int) Math.ceil(other.maxX); + this.maxY = (int) Math.ceil(other.maxY); + this.maxZ = (int) Math.ceil(other.maxZ); + } + + public void assign(GridAlignedBB other) { + this.minX = other.minX; + this.minY = other.minY; + this.minZ = other.minZ; + this.maxX = other.maxX; + this.maxY = other.maxY; + this.maxZ = other.maxZ; + } + public boolean intersects(GridAlignedBB other) { return this.intersects(other.minX, other.minY, other.minZ, other.maxX, other.maxY, other.maxZ); } @@ -297,5 +324,4 @@ public class GridAlignedBB { result = 31 * result + maxZ; return result; } - } diff --git a/src/main/java/com/jozufozu/flywheel/light/ILightUpdateListener.java b/src/main/java/com/jozufozu/flywheel/light/ILightUpdateListener.java index 13f890afc..ffbc00afd 100644 --- a/src/main/java/com/jozufozu/flywheel/light/ILightUpdateListener.java +++ b/src/main/java/com/jozufozu/flywheel/light/ILightUpdateListener.java @@ -1,32 +1,23 @@ package com.jozufozu.flywheel.light; -import net.minecraft.world.IBlockDisplayReader; import net.minecraft.world.LightType; -/** - * Anything can implement this, implementors should call {@link #startListening} - * appropriately to make sure they get the updates they want. - */ public interface ILightUpdateListener { - Volume getVolume(); + GridAlignedBB getVolume(); ListenerStatus status(); - default void startListening() { - LightUpdater.getInstance().addListener(this); - } - /** * Called when a light updates in a chunk the implementor cares about. */ - void onLightUpdate(IBlockDisplayReader world, LightType type, GridAlignedBB changed); + void onLightUpdate(LightProvider world, LightType type, GridAlignedBB changed); /** * Called when the server sends light data to the client. * */ - default void onLightPacket(IBlockDisplayReader world, int chunkX, int chunkZ) { + default void onLightPacket(LightProvider world, int chunkX, int chunkZ) { GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ); onLightUpdate(world, LightType.BLOCK, changedVolume); diff --git a/src/main/java/com/jozufozu/flywheel/light/IMovingListener.java b/src/main/java/com/jozufozu/flywheel/light/IMovingListener.java new file mode 100644 index 000000000..68ff331ed --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/light/IMovingListener.java @@ -0,0 +1,5 @@ +package com.jozufozu.flywheel.light; + +public interface IMovingListener extends ILightUpdateListener { + boolean update(LightProvider provider); +} diff --git a/src/main/java/com/jozufozu/flywheel/light/LightProvider.java b/src/main/java/com/jozufozu/flywheel/light/LightProvider.java new file mode 100644 index 000000000..226c4afa8 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/light/LightProvider.java @@ -0,0 +1,12 @@ +package com.jozufozu.flywheel.light; + +import net.minecraft.client.renderer.LightTexture; +import net.minecraft.world.LightType; + +public interface LightProvider { + int getLight(LightType type, int x, int y, int z); + + default int getPackedLight(int x, int y, int z) { + return LightTexture.pack(getLight(LightType.BLOCK, x, y, z), getLight(LightType.SKY, x, y, z)); + } +} diff --git a/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java b/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java index e1ff6c989..e0ba3072b 100644 --- a/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java +++ b/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java @@ -1,42 +1,42 @@ package com.jozufozu.flywheel.light; +import java.util.HashMap; +import java.util.Map; import java.util.Set; +import java.util.stream.Stream; import com.jozufozu.flywheel.util.WeakHashSet; import it.unimi.dsi.fastutil.longs.LongSet; -import net.minecraft.client.Minecraft; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.SectionPos; import net.minecraft.world.IBlockDisplayReader; import net.minecraft.world.LightType; +/** + * Keeps track of what chunks/sections each listener is in so we can update exactly what needs to be updated. + */ public class LightUpdater { - private static LightUpdater instance; - - public static LightUpdater getInstance() { - if (instance == null) instance = new LightUpdater(); - - return instance; + private static final Map light = new HashMap<>(); + public static LightUpdater get(IBlockDisplayReader world) { + return light.computeIfAbsent(world, LightUpdater::new); } - private final WeakHashSet allListeners; - private final WeakContainmentMultiMap sections; - private final WeakContainmentMultiMap chunks; + private final LightProvider provider; - public LightUpdater() { - allListeners = new WeakHashSet<>(); - sections = new WeakContainmentMultiMap<>(); - chunks = new WeakContainmentMultiMap<>(); + private final WeakHashSet movingListeners = new WeakHashSet<>(); + private final WeakContainmentMultiMap sections = new WeakContainmentMultiMap<>(); + private final WeakContainmentMultiMap chunks = new WeakContainmentMultiMap<>(); + + public LightUpdater(IBlockDisplayReader world) { + provider = BasicProvider.get(world); } public void tick() { - for (ILightUpdateListener listener : allListeners) { - if (listener.status() == ListenerStatus.UPDATE) { + for (IMovingListener listener : movingListeners) { + if (listener.update(provider)) { addListener(listener); - - listener.onLightUpdate(Minecraft.getInstance().level, LightType.BLOCK, null); } } } @@ -47,55 +47,41 @@ public class LightUpdater { * @param listener The object that wants to receive light update notifications. */ public void addListener(ILightUpdateListener listener) { - allListeners.add(listener); + if (listener instanceof IMovingListener) + movingListeners.add(((IMovingListener) listener)); - Volume volume = listener.getVolume(); + GridAlignedBB box = listener.getVolume(); LongSet sections = this.sections.getAndResetContainment(listener); LongSet chunks = this.chunks.getAndResetContainment(listener); - if (volume instanceof Volume.Block) { - BlockPos pos = ((Volume.Block) volume).pos; - long sectionPos = blockToSection(pos); - this.sections.put(sectionPos, listener); - sections.add(sectionPos); + int minX = SectionPos.blockToSectionCoord(box.minX); + int minY = SectionPos.blockToSectionCoord(box.minY); + int minZ = SectionPos.blockToSectionCoord(box.minZ); + int maxX = SectionPos.blockToSectionCoord(box.maxX); + int maxY = SectionPos.blockToSectionCoord(box.maxY); + int maxZ = SectionPos.blockToSectionCoord(box.maxZ); - long chunkPos = sectionToChunk(sectionPos); - this.chunks.put(chunkPos, listener); - chunks.add(chunkPos); - } else if (volume instanceof Volume.Box) { - GridAlignedBB box = ((Volume.Box) volume).box; - - int minX = SectionPos.blockToSectionCoord(box.minX); - int minY = SectionPos.blockToSectionCoord(box.minY); - int minZ = SectionPos.blockToSectionCoord(box.minZ); - int maxX = SectionPos.blockToSectionCoord(box.maxX); - int maxY = SectionPos.blockToSectionCoord(box.maxY); - int maxZ = SectionPos.blockToSectionCoord(box.maxZ); - - for (int x = minX; x <= maxX; x++) { - for (int z = minZ; z <= maxZ; z++) { - for (int y = minY; y <= maxY; y++) { - long sectionPos = SectionPos.asLong(x, y, z); - this.sections.put(sectionPos, listener); - sections.add(sectionPos); - } - long chunkPos = SectionPos.asLong(x, 0, z); - this.chunks.put(chunkPos, listener); - chunks.add(chunkPos); + for (int x = minX; x <= maxX; x++) { + for (int z = minZ; z <= maxZ; z++) { + for (int y = minY; y <= maxY; y++) { + long sectionPos = SectionPos.asLong(x, y, z); + this.sections.put(sectionPos, listener); + sections.add(sectionPos); } + long chunkPos = SectionPos.asLong(x, 0, z); + this.chunks.put(chunkPos, listener); + chunks.add(chunkPos); } } } /** * Dispatch light updates to all registered {@link ILightUpdateListener}s. - * - * @param world The world in which light was updated. * @param type The type of light that changed. * @param sectionPos A long representing the section position where light changed. */ - public void onLightUpdate(IBlockDisplayReader world, LightType type, long sectionPos) { + public void onLightUpdate(LightType type, long sectionPos) { Set set = sections.get(sectionPos); if (set == null || set.isEmpty()) return; @@ -105,7 +91,7 @@ public class LightUpdater { GridAlignedBB chunkBox = GridAlignedBB.from(SectionPos.of(sectionPos)); for (ILightUpdateListener listener : set) { - listener.onLightUpdate(world, type, chunkBox.copy()); + listener.onLightUpdate(provider, type, chunkBox.copy()); } } @@ -113,9 +99,8 @@ public class LightUpdater { * Dispatch light updates to all registered {@link ILightUpdateListener}s * when the server sends lighting data for an entire chunk. * - * @param world The world in which light was updated. */ - public void onLightPacket(IBlockDisplayReader world, int chunkX, int chunkZ) { + public void onLightPacket(int chunkX, int chunkZ) { long chunkPos = SectionPos.asLong(chunkX, 0, chunkZ); Set set = chunks.get(chunkPos); @@ -125,7 +110,7 @@ public class LightUpdater { set.removeIf(l -> l.status().shouldRemove()); for (ILightUpdateListener listener : set) { - listener.onLightPacket(world, chunkX, chunkZ); + listener.onLightPacket(provider, chunkX, chunkZ); } } @@ -136,4 +121,12 @@ public class LightUpdater { public static long sectionToChunk(long sectionPos) { return sectionPos & 0xFFFFFFFFFFF_00000L; } + + public Stream getAllBoxes() { + return chunks.stream().map(ILightUpdateListener::getVolume); + } + + public boolean isEmpty() { + return chunks.isEmpty(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/light/LightVolume.java b/src/main/java/com/jozufozu/flywheel/light/LightVolume.java index 41607a164..9e4ea178e 100644 --- a/src/main/java/com/jozufozu/flywheel/light/LightVolume.java +++ b/src/main/java/com/jozufozu/flywheel/light/LightVolume.java @@ -124,11 +124,12 @@ public class LightVolume { if (removed) return; if (textureVolume.contains(newSampleVolume)) { + BasicProvider basicProvider = BasicProvider.get(world); if (newSampleVolume.intersects(sampleVolume)) { GridAlignedBB newArea = newSampleVolume.intersect(sampleVolume); sampleVolume = newSampleVolume; - copyLight(world, newArea); + copyLight(basicProvider, newArea); } else { sampleVolume = newSampleVolume; initialize(world); @@ -143,7 +144,7 @@ public class LightVolume { } } - public void notifyLightUpdate(IBlockDisplayReader world, LightType type, GridAlignedBB changedVolume) { + public void notifyLightUpdate(LightProvider world, LightType type, GridAlignedBB changedVolume) { if (removed) return; if (!changedVolume.intersects(sampleVolume)) return; @@ -153,7 +154,7 @@ public class LightVolume { else if (type == LightType.SKY) copySky(world, changedVolume); } - public void notifyLightPacket(IBlockDisplayReader world, int chunkX, int chunkZ) { + public void notifyLightPacket(LightProvider world, int chunkX, int chunkZ) { if (removed) return; GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ); @@ -193,17 +194,13 @@ public class LightVolume { * * @param worldVolume the region in the world to copy data from. */ - public void copyBlock(IBlockDisplayReader world, GridAlignedBB worldVolume) { - BlockPos.Mutable pos = new BlockPos.Mutable(); - + public void copyBlock(LightProvider world, GridAlignedBB worldVolume) { int xShift = textureVolume.minX; int yShift = textureVolume.minY; int zShift = textureVolume.minZ; worldVolume.forEachContained((x, y, z) -> { - pos.set(x, y, z); - - int light = world.getBrightness(LightType.BLOCK, pos); + int light = world.getLight(LightType.BLOCK, x, y, z); writeBlock(x - xShift, y - yShift, z - zShift, light); }); @@ -216,17 +213,13 @@ public class LightVolume { * * @param worldVolume the region in the world to copy data from. */ - public void copySky(IBlockDisplayReader world, GridAlignedBB worldVolume) { - BlockPos.Mutable pos = new BlockPos.Mutable(); - + public void copySky(LightProvider world, GridAlignedBB worldVolume) { int xShift = textureVolume.minX; int yShift = textureVolume.minY; int zShift = textureVolume.minZ; worldVolume.forEachContained((x, y, z) -> { - pos.set(x, y, z); - - int light = world.getBrightness(LightType.SKY, pos); + int light = world.getLight(LightType.SKY, x, y, z); writeSky(x - xShift, y - yShift, z - zShift, light); }); @@ -239,7 +232,7 @@ public class LightVolume { * * @param worldVolume the region in the world to copy data from. */ - public void copyLight(IBlockDisplayReader world, GridAlignedBB worldVolume) { + public void copyLight(LightProvider world, GridAlignedBB worldVolume) { BlockPos.Mutable pos = new BlockPos.Mutable(); int xShift = textureVolume.minX; @@ -249,8 +242,8 @@ public class LightVolume { worldVolume.forEachContained((x, y, z) -> { pos.set(x, y, z); - int block = world.getBrightness(LightType.BLOCK, pos); - int sky = world.getBrightness(LightType.SKY, pos); + int block = world.getLight(LightType.BLOCK, x, y, z); + int sky = world.getLight(LightType.SKY, x, y, z); writeLight(x - xShift, y - yShift, z - zShift, block, sky); }); diff --git a/src/main/java/com/jozufozu/flywheel/light/Volume.java b/src/main/java/com/jozufozu/flywheel/light/Volume.java deleted file mode 100644 index b812bba71..000000000 --- a/src/main/java/com/jozufozu/flywheel/light/Volume.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.jozufozu.flywheel.light; - -import net.minecraft.util.math.AxisAlignedBB; -import net.minecraft.util.math.BlockPos; - -public class Volume { - - public static Volume.Block block(BlockPos pos) { - return new Block(pos); - } - - public static Volume.Box box(GridAlignedBB box) { - return new Box(box); - } - - public static Volume.Box box(AxisAlignedBB box) { - return new Box(GridAlignedBB.from(box)); - } - - public static class Block extends Volume { - public final BlockPos pos; - - public Block(BlockPos pos) { - this.pos = pos; - } - } - - public static class Box extends Volume { - public final GridAlignedBB box; - - public Box(GridAlignedBB box) { - this.box = box; - } - } -} diff --git a/src/main/java/com/jozufozu/flywheel/light/WeakContainmentMultiMap.java b/src/main/java/com/jozufozu/flywheel/light/WeakContainmentMultiMap.java index 944e75a75..e884ec706 100644 --- a/src/main/java/com/jozufozu/flywheel/light/WeakContainmentMultiMap.java +++ b/src/main/java/com/jozufozu/flywheel/light/WeakContainmentMultiMap.java @@ -1,5 +1,8 @@ package com.jozufozu.flywheel.light; +import java.util.AbstractCollection; +import java.util.Collection; +import java.util.Iterator; import java.util.Set; import java.util.WeakHashMap; import java.util.function.LongConsumer; @@ -11,7 +14,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; import it.unimi.dsi.fastutil.longs.LongRBTreeSet; import it.unimi.dsi.fastutil.longs.LongSet; -public class WeakContainmentMultiMap { +public class WeakContainmentMultiMap extends AbstractCollection { private final Long2ObjectMap> forward; private final WeakHashMap reverse; @@ -53,4 +56,14 @@ public class WeakContainmentMultiMap { public void put(long sectionPos, T listener) { forward.computeIfAbsent(sectionPos, $ -> new WeakHashSet<>()).add(listener); } + + @Override + public Iterator iterator() { + return reverse.keySet().iterator(); + } + + @Override + public int size() { + return reverse.size(); + } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/light/LightUpdateMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/light/LightUpdateMixin.java index 6a6ab7f73..f7a50f36e 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/light/LightUpdateMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/light/LightUpdateMixin.java @@ -1,25 +1,17 @@ package com.jozufozu.flywheel.mixin.light; -import java.util.Map; - import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; -import com.jozufozu.flywheel.backend.instancing.InstanceManager; -import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.light.LightUpdater; -import com.jozufozu.flywheel.util.ChunkUtil; import net.minecraft.client.multiplayer.ClientChunkProvider; import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; -import net.minecraft.tileentity.TileEntity; import net.minecraft.util.math.SectionPos; import net.minecraft.world.LightType; import net.minecraft.world.chunk.AbstractChunkProvider; -import net.minecraft.world.chunk.Chunk; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.OnlyIn; @@ -38,7 +30,7 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider { ClientChunkProvider thi = ((ClientChunkProvider) (Object) this); ClientWorld world = (ClientWorld) thi.getLevel(); - LightUpdater.getInstance() - .onLightUpdate(world, type, pos.asLong()); + LightUpdater.get(world) + .onLightUpdate(type, pos.asLong()); } } diff --git a/src/main/java/com/jozufozu/flywheel/mixin/light/NetworkLightUpdateMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/light/NetworkLightUpdateMixin.java index ed396c31d..2d7f2243b 100644 --- a/src/main/java/com/jozufozu/flywheel/mixin/light/NetworkLightUpdateMixin.java +++ b/src/main/java/com/jozufozu/flywheel/mixin/light/NetworkLightUpdateMixin.java @@ -1,25 +1,17 @@ package com.jozufozu.flywheel.mixin.light; -import java.util.Arrays; - import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import com.jozufozu.flywheel.backend.RenderWork; -import com.jozufozu.flywheel.backend.instancing.InstanceManager; -import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.light.LightUpdater; import net.minecraft.client.Minecraft; import net.minecraft.client.network.play.ClientPlayNetHandler; import net.minecraft.client.world.ClientWorld; -import net.minecraft.entity.Entity; import net.minecraft.network.play.server.SUpdateLightPacket; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.ClassInheritanceMultiMap; -import net.minecraft.world.chunk.Chunk; @Mixin(ClientPlayNetHandler.class) public class NetworkLightUpdateMixin { @@ -34,8 +26,8 @@ public class NetworkLightUpdateMixin { int chunkX = packet.getX(); int chunkZ = packet.getZ(); - LightUpdater.getInstance() - .onLightPacket(world, chunkX, chunkZ); + LightUpdater.get(world) + .onLightPacket(chunkX, chunkZ); }); } } diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java index d7911e195..7fc97ef03 100644 --- a/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java +++ b/src/main/java/com/jozufozu/flywheel/vanilla/ChestInstance.java @@ -31,6 +31,7 @@ import net.minecraft.util.math.vector.Vector3f; public class ChestInstance extends TileEntityInstance implements IDynamicInstance { + private final MatrixTransformStack stack = new MatrixTransformStack(); private final OrientedData body; private final ModelData lid; @@ -91,9 +92,8 @@ public class ChestInstance extends TileEntityI float angleX = -(progress * ((float) Math.PI / 2F)); - MatrixTransformStack stack = new MatrixTransformStack(); - - stack.translate(getInstancePosition()) + stack.setIdentity() + .translate(getInstancePosition()) .translate(0, 9f/16f, 0) .centre() .multiply(baseRotation)