mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 23:47:09 +01:00
Moving light updates
- Better system for moving objects that want to receive light updates - LightProvider interface to better abstract light lookups - All light listeners use GridAlignedBBs - More utility in GridAlignedBB
This commit is contained in:
parent
7ca4ea5c3e
commit
fe304041c5
19 changed files with 191 additions and 168 deletions
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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<T> 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);
|
||||
|
|
|
@ -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 <E> The type of {@link Entity} your class is an instance of.
|
||||
*/
|
||||
public abstract class EntityInstance<E extends Entity> extends AbstractInstance implements ILightUpdateListener {
|
||||
public abstract class EntityInstance<E extends Entity> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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<T extends TileEntity> extends AbstractI
|
|||
}
|
||||
|
||||
@Override
|
||||
public Volume.Block getVolume() {
|
||||
return Volume.block(pos);
|
||||
public GridAlignedBB getVolume() {
|
||||
return GridAlignedBB.from(pos);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
30
src/main/java/com/jozufozu/flywheel/light/BasicProvider.java
Normal file
30
src/main/java/com/jozufozu/flywheel/light/BasicProvider.java
Normal file
|
@ -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<IBlockDisplayReader, BasicProvider> 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));
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
package com.jozufozu.flywheel.light;
|
||||
|
||||
public interface IMovingListener extends ILightUpdateListener {
|
||||
boolean update(LightProvider provider);
|
||||
}
|
12
src/main/java/com/jozufozu/flywheel/light/LightProvider.java
Normal file
12
src/main/java/com/jozufozu/flywheel/light/LightProvider.java
Normal file
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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<IBlockDisplayReader, LightUpdater> light = new HashMap<>();
|
||||
public static LightUpdater get(IBlockDisplayReader world) {
|
||||
return light.computeIfAbsent(world, LightUpdater::new);
|
||||
}
|
||||
|
||||
private final WeakHashSet<ILightUpdateListener> allListeners;
|
||||
private final WeakContainmentMultiMap<ILightUpdateListener> sections;
|
||||
private final WeakContainmentMultiMap<ILightUpdateListener> chunks;
|
||||
private final LightProvider provider;
|
||||
|
||||
public LightUpdater() {
|
||||
allListeners = new WeakHashSet<>();
|
||||
sections = new WeakContainmentMultiMap<>();
|
||||
chunks = new WeakContainmentMultiMap<>();
|
||||
private final WeakHashSet<IMovingListener> movingListeners = new WeakHashSet<>();
|
||||
private final WeakContainmentMultiMap<ILightUpdateListener> sections = new WeakContainmentMultiMap<>();
|
||||
private final WeakContainmentMultiMap<ILightUpdateListener> 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<ILightUpdateListener> 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<ILightUpdateListener> 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<GridAlignedBB> getAllBoxes() {
|
||||
return chunks.stream().map(ILightUpdateListener::getVolume);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return chunks.isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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<T> {
|
||||
public class WeakContainmentMultiMap<T> extends AbstractCollection<T> {
|
||||
|
||||
private final Long2ObjectMap<WeakHashSet<T>> forward;
|
||||
private final WeakHashMap<T, LongSet> reverse;
|
||||
|
@ -53,4 +56,14 @@ public class WeakContainmentMultiMap<T> {
|
|||
public void put(long sectionPos, T listener) {
|
||||
forward.computeIfAbsent(sectionPos, $ -> new WeakHashSet<>()).add(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return reverse.keySet().iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return reverse.size();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import net.minecraft.util.math.vector.Vector3f;
|
|||
|
||||
public class ChestInstance<T extends TileEntity & IChestLid> extends TileEntityInstance<T> implements IDynamicInstance {
|
||||
|
||||
private final MatrixTransformStack stack = new MatrixTransformStack();
|
||||
private final OrientedData body;
|
||||
private final ModelData lid;
|
||||
|
||||
|
@ -91,9 +92,8 @@ public class ChestInstance<T extends TileEntity & IChestLid> 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)
|
||||
|
|
Loading…
Reference in a new issue