mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-02-27 20:24:39 +01:00
Update light updates
- Remove NetworkLightUpdateMixin and associated code - Do not defer level renderer reload when changing backend - Remove RenderWork - Reset DrawBuffer on free - Move CoordinateConsumer inside ImmutableBox - Rename GridAlignedBB -> MutableBox - Rename LightListener#isListenerInvalid -> #isInvalid - Move package light -> lib.light - Move package util.box -> lib.box
This commit is contained in:
parent
a1910f06d4
commit
f2d55a5001
28 changed files with 131 additions and 260 deletions
|
@ -20,7 +20,6 @@ import com.jozufozu.flywheel.lib.model.PartialModel;
|
||||||
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
import com.jozufozu.flywheel.lib.pipeline.Pipelines;
|
||||||
import com.jozufozu.flywheel.lib.struct.StructTypes;
|
import com.jozufozu.flywheel.lib.struct.StructTypes;
|
||||||
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
import com.jozufozu.flywheel.lib.util.QuadConverter;
|
||||||
import com.jozufozu.flywheel.lib.util.RenderWork;
|
|
||||||
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
import com.jozufozu.flywheel.lib.util.ShadersModHandler;
|
||||||
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
|
import com.jozufozu.flywheel.mixin.PausedPartialTickAccessor;
|
||||||
import com.jozufozu.flywheel.vanilla.VanillaInstances;
|
import com.jozufozu.flywheel.vanilla.VanillaInstances;
|
||||||
|
@ -97,8 +96,6 @@ public class Flywheel {
|
||||||
forgeEventBus.addListener(ForgeEvents::unloadWorld);
|
forgeEventBus.addListener(ForgeEvents::unloadWorld);
|
||||||
forgeEventBus.addListener(ForgeEvents::tickLight);
|
forgeEventBus.addListener(ForgeEvents::tickLight);
|
||||||
|
|
||||||
forgeEventBus.addListener(EventPriority.LOWEST, RenderWork::onRenderLevelLast);
|
|
||||||
|
|
||||||
modEventBus.addListener(PartialModel::onModelRegistry);
|
modEventBus.addListener(PartialModel::onModelRegistry);
|
||||||
modEventBus.addListener(PartialModel::onModelBake);
|
modEventBus.addListener(PartialModel::onModelBake);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import com.jozufozu.flywheel.api.backend.BackendType;
|
||||||
import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor;
|
import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor;
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.lib.backend.BackendTypes;
|
import com.jozufozu.flywheel.lib.backend.BackendTypes;
|
||||||
import com.jozufozu.flywheel.lib.util.RenderWork;
|
|
||||||
import com.mojang.logging.LogUtils;
|
import com.mojang.logging.LogUtils;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -86,7 +85,7 @@ public class Backend {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reloadWorldRenderers() {
|
public static void reloadWorldRenderers() {
|
||||||
RenderWork.enqueue(Minecraft.getInstance().levelRenderer::allChanged);
|
Minecraft.getInstance().levelRenderer.allChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static BackendType chooseEngine() {
|
private static BackendType chooseEngine() {
|
||||||
|
|
|
@ -127,6 +127,8 @@ public class DrawBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void free() {
|
public void free() {
|
||||||
|
reset();
|
||||||
|
|
||||||
if (memory == null) {
|
if (memory == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,10 +9,10 @@ import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.api.instancer.FlatLit;
|
import com.jozufozu.flywheel.api.instancer.FlatLit;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.light.LightListener;
|
import com.jozufozu.flywheel.lib.light.LightListener;
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ public abstract class AbstractInstance implements Instance, LightListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isListenerInvalid() {
|
public boolean isInvalid() {
|
||||||
return removed;
|
return removed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,7 +96,7 @@ public abstract class AbstractInstance implements Instance, LightListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLightUpdate(LightLayer type, ImmutableBox changed) {
|
public void onLightUpdate(LightLayer type, SectionPos pos) {
|
||||||
updateLight();
|
updateLight();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import com.jozufozu.flywheel.backend.instancing.ratelimit.DistanceUpdateLimiter;
|
||||||
import com.jozufozu.flywheel.backend.instancing.ratelimit.NonLimiter;
|
import com.jozufozu.flywheel.backend.instancing.ratelimit.NonLimiter;
|
||||||
import com.jozufozu.flywheel.backend.instancing.storage.Storage;
|
import com.jozufozu.flywheel.backend.instancing.storage.Storage;
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
import com.jozufozu.flywheel.api.instancer.InstancedPart;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
import com.jozufozu.flywheel.lib.box.MutableBox;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
@ -90,7 +90,7 @@ public abstract class BlockEntityInstance<T extends BlockEntity> extends Abstrac
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ImmutableBox getVolume() {
|
public ImmutableBox getVolume() {
|
||||||
return GridAlignedBB.from(pos);
|
return MutableBox.from(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -9,7 +9,7 @@ import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.storage.AbstractStorage;
|
import com.jozufozu.flywheel.backend.instancing.storage.AbstractStorage;
|
||||||
import com.jozufozu.flywheel.backend.instancing.storage.Storage;
|
import com.jozufozu.flywheel.backend.instancing.storage.Storage;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||||
|
|
||||||
public class EffectInstanceManager extends InstanceManager<Effect> {
|
public class EffectInstanceManager extends InstanceManager<Effect> {
|
||||||
|
|
||||||
|
|
|
@ -7,9 +7,9 @@ import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceManager;
|
||||||
import com.jozufozu.flywheel.light.LightListener;
|
import com.jozufozu.flywheel.lib.box.MutableBox;
|
||||||
import com.jozufozu.flywheel.light.TickingLightListener;
|
import com.jozufozu.flywheel.lib.light.LightListener;
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
import com.jozufozu.flywheel.lib.light.TickingLightListener;
|
||||||
import com.mojang.math.Vector3f;
|
import com.mojang.math.Vector3f;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -38,16 +38,16 @@ import net.minecraft.world.phys.Vec3;
|
||||||
public abstract class EntityInstance<E extends Entity> extends AbstractInstance implements LightListener, TickingLightListener {
|
public abstract class EntityInstance<E extends Entity> extends AbstractInstance implements LightListener, TickingLightListener {
|
||||||
|
|
||||||
protected final E entity;
|
protected final E entity;
|
||||||
protected final GridAlignedBB bounds;
|
protected final MutableBox bounds;
|
||||||
|
|
||||||
public EntityInstance(InstancerManager instancerManager, E entity) {
|
public EntityInstance(InstancerManager instancerManager, E entity) {
|
||||||
super(instancerManager, entity.level);
|
super(instancerManager, entity.level);
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
bounds = GridAlignedBB.from(entity.getBoundingBox());
|
bounds = MutableBox.from(entity.getBoundingBox());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GridAlignedBB getVolume() {
|
public MutableBox getVolume() {
|
||||||
return bounds;
|
return bounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.jozufozu.flywheel.api.instance.DynamicInstance;
|
||||||
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
import com.jozufozu.flywheel.api.instance.TickableInstance;
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||||
|
|
||||||
public abstract class AbstractStorage<T> implements Storage<T> {
|
public abstract class AbstractStorage<T> implements Storage<T> {
|
||||||
protected final List<TickableInstance> tickableInstances;
|
protected final List<TickableInstance> tickableInstances;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||||
|
|
||||||
public abstract class One2OneStorage<T> extends AbstractStorage<T> {
|
public abstract class One2OneStorage<T> extends AbstractStorage<T> {
|
||||||
private final Map<T, AbstractInstance> instances;
|
private final Map<T, AbstractInstance> instances;
|
||||||
|
|
|
@ -5,8 +5,8 @@ import java.util.ArrayList;
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
|
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||||
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
|
import com.jozufozu.flywheel.lib.memory.FlwMemoryTracker;
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
|
||||||
import com.jozufozu.flywheel.util.StringUtil;
|
import com.jozufozu.flywheel.util.StringUtil;
|
||||||
import com.jozufozu.flywheel.util.WorldAttached;
|
import com.jozufozu.flywheel.util.WorldAttached;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.util.box;
|
package com.jozufozu.flywheel.lib.box;
|
||||||
|
|
||||||
import static com.jozufozu.flywheel.util.RenderMath.isPowerOf2;
|
import static com.jozufozu.flywheel.util.RenderMath.isPowerOf2;
|
||||||
|
|
||||||
|
@ -65,14 +65,14 @@ public interface ImmutableBox {
|
||||||
return isPowerOf2(volume());
|
return isPowerOf2(volume());
|
||||||
}
|
}
|
||||||
|
|
||||||
default GridAlignedBB intersect(ImmutableBox other) {
|
default MutableBox intersect(ImmutableBox other) {
|
||||||
int minX = Math.max(this.getMinX(), other.getMinX());
|
int minX = Math.max(this.getMinX(), other.getMinX());
|
||||||
int minY = Math.max(this.getMinY(), other.getMinY());
|
int minY = Math.max(this.getMinY(), other.getMinY());
|
||||||
int minZ = Math.max(this.getMinZ(), other.getMinZ());
|
int minZ = Math.max(this.getMinZ(), other.getMinZ());
|
||||||
int maxX = Math.min(this.getMaxX(), other.getMaxX());
|
int maxX = Math.min(this.getMaxX(), other.getMaxX());
|
||||||
int maxY = Math.min(this.getMaxY(), other.getMaxY());
|
int maxY = Math.min(this.getMaxY(), other.getMaxY());
|
||||||
int maxZ = Math.min(this.getMaxZ(), other.getMaxZ());
|
int maxZ = Math.min(this.getMaxZ(), other.getMaxZ());
|
||||||
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
default ImmutableBox union(ImmutableBox other) {
|
default ImmutableBox union(ImmutableBox other) {
|
||||||
|
@ -82,7 +82,7 @@ public interface ImmutableBox {
|
||||||
int maxX = Math.max(this.getMaxX(), other.getMaxX());
|
int maxX = Math.max(this.getMaxX(), other.getMaxX());
|
||||||
int maxY = Math.max(this.getMaxY(), other.getMaxY());
|
int maxY = Math.max(this.getMaxY(), other.getMaxY());
|
||||||
int maxZ = Math.max(this.getMaxZ(), other.getMaxZ());
|
int maxZ = Math.max(this.getMaxZ(), other.getMaxZ());
|
||||||
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ public interface ImmutableBox {
|
||||||
&& other.getMaxZ() <= this.getMaxZ();
|
&& other.getMaxZ() <= this.getMaxZ();
|
||||||
}
|
}
|
||||||
|
|
||||||
default boolean isContainedBy(GridAlignedBB other) {
|
default boolean isContainedBy(MutableBox other) {
|
||||||
return other.contains(this);
|
return other.contains(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,12 @@ public interface ImmutableBox {
|
||||||
return new AABB(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
|
return new AABB(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
default GridAlignedBB copy() {
|
default MutableBox copy() {
|
||||||
return new GridAlignedBB(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
|
return new MutableBox(getMinX(), getMinY(), getMinZ(), getMaxX(), getMaxY(), getMaxZ());
|
||||||
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
interface CoordinateConsumer {
|
||||||
|
void consume(int x, int y, int z);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.util.box;
|
package com.jozufozu.flywheel.lib.box;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.core.Vec3i;
|
import net.minecraft.core.Vec3i;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
public class GridAlignedBB implements ImmutableBox {
|
public class MutableBox implements ImmutableBox {
|
||||||
private int minX;
|
private int minX;
|
||||||
private int minY;
|
private int minY;
|
||||||
private int minZ;
|
private int minZ;
|
||||||
|
@ -18,11 +18,11 @@ public class GridAlignedBB implements ImmutableBox {
|
||||||
private int maxY;
|
private int maxY;
|
||||||
private int maxZ;
|
private int maxZ;
|
||||||
|
|
||||||
public GridAlignedBB() {
|
public MutableBox() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
public MutableBox(int minX, int minY, int minZ, int maxX, int maxY, int maxZ) {
|
||||||
this.minX = minX;
|
this.minX = minX;
|
||||||
this.minY = minY;
|
this.minY = minY;
|
||||||
this.minZ = minZ;
|
this.minZ = minZ;
|
||||||
|
@ -31,41 +31,41 @@ public class GridAlignedBB implements ImmutableBox {
|
||||||
this.maxZ = maxZ;
|
this.maxZ = maxZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB ofRadius(int radius) {
|
public static MutableBox ofRadius(int radius) {
|
||||||
return new GridAlignedBB(-radius, -radius, -radius, radius + 1, radius + 1, radius + 1);
|
return new MutableBox(-radius, -radius, -radius, radius + 1, radius + 1, radius + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB from(AABB aabb) {
|
public static MutableBox from(AABB aabb) {
|
||||||
int minX = (int) Math.floor(aabb.minX);
|
int minX = (int) Math.floor(aabb.minX);
|
||||||
int minY = (int) Math.floor(aabb.minY);
|
int minY = (int) Math.floor(aabb.minY);
|
||||||
int minZ = (int) Math.floor(aabb.minZ);
|
int minZ = (int) Math.floor(aabb.minZ);
|
||||||
int maxX = (int) Math.ceil(aabb.maxX);
|
int maxX = (int) Math.ceil(aabb.maxX);
|
||||||
int maxY = (int) Math.ceil(aabb.maxY);
|
int maxY = (int) Math.ceil(aabb.maxY);
|
||||||
int maxZ = (int) Math.ceil(aabb.maxZ);
|
int maxZ = (int) Math.ceil(aabb.maxZ);
|
||||||
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB from(SectionPos pos) {
|
public static MutableBox from(SectionPos pos) {
|
||||||
return new GridAlignedBB(pos.minBlockX(), pos.minBlockY(), pos.minBlockZ(), pos.maxBlockX() + 1, pos.maxBlockY() + 1, pos.maxBlockZ() + 1);
|
return new MutableBox(pos.minBlockX(), pos.minBlockY(), pos.minBlockZ(), pos.maxBlockX() + 1, pos.maxBlockY() + 1, pos.maxBlockZ() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB from(BlockPos start, BlockPos end) {
|
public static MutableBox from(BlockPos start, BlockPos end) {
|
||||||
return new GridAlignedBB(start.getX(), start.getY(), start.getZ(), end.getX() + 1, end.getY() + 1, end.getZ() + 1);
|
return new MutableBox(start.getX(), start.getY(), start.getZ(), end.getX() + 1, end.getY() + 1, end.getZ() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB from(BlockPos pos) {
|
public static MutableBox from(BlockPos pos) {
|
||||||
return new GridAlignedBB(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1);
|
return new MutableBox(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridAlignedBB from(int sectionX, int sectionZ) {
|
public static MutableBox from(int sectionX, int sectionZ) {
|
||||||
int startX = sectionX << 4;
|
int startX = sectionX << 4;
|
||||||
int startZ = sectionZ << 4;
|
int startZ = sectionZ << 4;
|
||||||
return new GridAlignedBB(startX, 0, startZ, startX + 16, 256, startZ + 16);
|
return new MutableBox(startX, 0, startZ, startX + 16, 256, startZ + 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImmutableBox containingAll(Collection<BlockPos> positions) {
|
public static ImmutableBox containingAll(Collection<BlockPos> positions) {
|
||||||
if (positions.isEmpty()) {
|
if (positions.isEmpty()) {
|
||||||
return new GridAlignedBB();
|
return new MutableBox();
|
||||||
}
|
}
|
||||||
int minX = Integer.MAX_VALUE;
|
int minX = Integer.MAX_VALUE;
|
||||||
int minY = Integer.MAX_VALUE;
|
int minY = Integer.MAX_VALUE;
|
||||||
|
@ -81,7 +81,7 @@ public class GridAlignedBB implements ImmutableBox {
|
||||||
maxY = Math.max(maxY, pos.getY());
|
maxY = Math.max(maxY, pos.getY());
|
||||||
maxZ = Math.max(maxZ, pos.getZ());
|
maxZ = Math.max(maxZ, pos.getZ());
|
||||||
}
|
}
|
||||||
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void fixMinMax() {
|
public void fixMinMax() {
|
||||||
|
@ -277,37 +277,37 @@ public class GridAlignedBB implements ImmutableBox {
|
||||||
return maxZ;
|
return maxZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMinX(int minX) {
|
public MutableBox setMinX(int minX) {
|
||||||
this.minX = minX;
|
this.minX = minX;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMinY(int minY) {
|
public MutableBox setMinY(int minY) {
|
||||||
this.minY = minY;
|
this.minY = minY;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMinZ(int minZ) {
|
public MutableBox setMinZ(int minZ) {
|
||||||
this.minZ = minZ;
|
this.minZ = minZ;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMaxX(int maxX) {
|
public MutableBox setMaxX(int maxX) {
|
||||||
this.maxX = maxX;
|
this.maxX = maxX;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMaxY(int maxY) {
|
public MutableBox setMaxY(int maxY) {
|
||||||
this.maxY = maxY;
|
this.maxY = maxY;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMaxZ(int maxZ) {
|
public MutableBox setMaxZ(int maxZ) {
|
||||||
this.maxZ = maxZ;
|
this.maxZ = maxZ;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB assign(BlockPos start, BlockPos end) {
|
public MutableBox assign(BlockPos start, BlockPos end) {
|
||||||
minX = start.getX();
|
minX = start.getX();
|
||||||
minY = start.getY();
|
minY = start.getY();
|
||||||
minZ = start.getZ();
|
minZ = start.getZ();
|
||||||
|
@ -317,22 +317,22 @@ public class GridAlignedBB implements ImmutableBox {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMax(Vec3i v) {
|
public MutableBox setMax(Vec3i v) {
|
||||||
return setMax(v.getX(), v.getY(), v.getZ());
|
return setMax(v.getX(), v.getY(), v.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMin(Vec3i v) {
|
public MutableBox setMin(Vec3i v) {
|
||||||
return setMin(v.getX(), v.getY(), v.getZ());
|
return setMin(v.getX(), v.getY(), v.getZ());
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMax(int x, int y, int z) {
|
public MutableBox setMax(int x, int y, int z) {
|
||||||
maxX = x;
|
maxX = x;
|
||||||
maxY = y;
|
maxY = y;
|
||||||
maxZ = z;
|
maxZ = z;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public GridAlignedBB setMin(int x, int y, int z) {
|
public MutableBox setMin(int x, int y, int z) {
|
||||||
minX = x;
|
minX = x;
|
||||||
minY = y;
|
minY = y;
|
||||||
minZ = z;
|
minZ = z;
|
||||||
|
@ -376,14 +376,14 @@ public class GridAlignedBB implements ImmutableBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GridAlignedBB intersect(ImmutableBox other) {
|
public MutableBox intersect(ImmutableBox other) {
|
||||||
int minX = Math.max(this.minX, other.getMinX());
|
int minX = Math.max(this.minX, other.getMinX());
|
||||||
int minY = Math.max(this.minY, other.getMinY());
|
int minY = Math.max(this.minY, other.getMinY());
|
||||||
int minZ = Math.max(this.minZ, other.getMinZ());
|
int minZ = Math.max(this.minZ, other.getMinZ());
|
||||||
int maxX = Math.min(this.maxX, other.getMaxX());
|
int maxX = Math.min(this.maxX, other.getMaxX());
|
||||||
int maxY = Math.min(this.maxY, other.getMaxY());
|
int maxY = Math.min(this.maxY, other.getMaxY());
|
||||||
int maxZ = Math.min(this.maxZ, other.getMaxZ());
|
int maxZ = Math.min(this.maxZ, other.getMaxZ());
|
||||||
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -394,7 +394,7 @@ public class GridAlignedBB implements ImmutableBox {
|
||||||
int maxX = Math.max(this.maxX, other.getMaxX());
|
int maxX = Math.max(this.maxX, other.getMaxX());
|
||||||
int maxY = Math.max(this.maxY, other.getMaxY());
|
int maxY = Math.max(this.maxY, other.getMaxY());
|
||||||
int maxZ = Math.max(this.maxZ, other.getMaxZ());
|
int maxZ = Math.max(this.maxZ, other.getMaxZ());
|
||||||
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -426,8 +426,8 @@ public class GridAlignedBB implements ImmutableBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GridAlignedBB copy() {
|
public MutableBox copy() {
|
||||||
return new GridAlignedBB(minX, minY, minZ, maxX, maxY, maxZ);
|
return new MutableBox(minX, minY, minZ, maxX, maxY, maxZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
|
@ -1,9 +1,10 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.lib.light;
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||||
|
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
|
|
||||||
public class DummyLightUpdater extends LightUpdater {
|
public class DummyLightUpdater extends LightUpdater {
|
||||||
|
@ -29,12 +30,7 @@ public class DummyLightUpdater extends LightUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLightUpdate(LightLayer type, long sectionPos) {
|
public void onLightUpdate(LightLayer type, SectionPos pos) {
|
||||||
// noop
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLightPacket(int chunkX, int chunkZ) {
|
|
||||||
// noop
|
// noop
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.lib.light;
|
||||||
|
|
||||||
import static org.lwjgl.opengl.GL11.GL_LINEAR;
|
import static org.lwjgl.opengl.GL11.GL_LINEAR;
|
||||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
|
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
|
||||||
|
@ -23,14 +23,14 @@ import org.lwjgl.opengl.GL30;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.gl.GlTexture;
|
import com.jozufozu.flywheel.gl.GlTexture;
|
||||||
import com.jozufozu.flywheel.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
import com.jozufozu.flywheel.lib.box.MutableBox;
|
||||||
|
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
|
|
||||||
public class GPULightVolume extends LightVolume {
|
public class GPULightVolume extends LightVolume {
|
||||||
|
|
||||||
protected final GridAlignedBB sampleVolume = new GridAlignedBB();
|
protected final MutableBox sampleVolume = new MutableBox();
|
||||||
private final GlTexture glTexture;
|
private final GlTexture glTexture;
|
||||||
|
|
||||||
private final GlTextureUnit textureUnit = GlTextureUnit.T4;
|
private final GlTextureUnit textureUnit = GlTextureUnit.T4;
|
|
@ -1,8 +1,8 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.lib.light;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
|
||||||
|
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,22 +20,10 @@ public interface LightListener {
|
||||||
* @return {@code true} if the listener is invalid/removed/deleted,
|
* @return {@code true} if the listener is invalid/removed/deleted,
|
||||||
* and should no longer receive updates.
|
* and should no longer receive updates.
|
||||||
*/
|
*/
|
||||||
boolean isListenerInvalid();
|
boolean isInvalid();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when a light updates in a chunk the implementor cares about.
|
* Called when a light updates in a chunk the implementor cares about.
|
||||||
*/
|
*/
|
||||||
void onLightUpdate(LightLayer type, ImmutableBox changed);
|
void onLightUpdate(LightLayer type, SectionPos pos);
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the server sends light data to the client.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
default void onLightPacket(int chunkX, int chunkZ) {
|
|
||||||
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
|
|
||||||
|
|
||||||
onLightUpdate(LightLayer.BLOCK, changedVolume);
|
|
||||||
|
|
||||||
onLightUpdate(LightLayer.SKY, changedVolume);
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.lib.light;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for bit-twiddling light.
|
* Utility class for bit-twiddling light.
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.lib.light;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.lib.light;
|
||||||
|
|
||||||
import java.util.Queue;
|
import java.util.Queue;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -6,15 +6,12 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.Backend;
|
import com.jozufozu.flywheel.backend.Backend;
|
||||||
import com.jozufozu.flywheel.backend.task.ParallelTaskExecutor;
|
|
||||||
import com.jozufozu.flywheel.backend.task.WorkGroup;
|
import com.jozufozu.flywheel.backend.task.WorkGroup;
|
||||||
|
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||||
import com.jozufozu.flywheel.util.FlwUtil;
|
import com.jozufozu.flywheel.util.FlwUtil;
|
||||||
import com.jozufozu.flywheel.util.WorldAttached;
|
import com.jozufozu.flywheel.util.WorldAttached;
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
|
@ -28,7 +25,11 @@ import net.minecraft.world.level.LightLayer;
|
||||||
public class LightUpdater {
|
public class LightUpdater {
|
||||||
|
|
||||||
private static final WorldAttached<LightUpdater> LEVELS = new WorldAttached<>(LightUpdater::new);
|
private static final WorldAttached<LightUpdater> LEVELS = new WorldAttached<>(LightUpdater::new);
|
||||||
private final ParallelTaskExecutor taskExecutor;
|
|
||||||
|
private final LevelAccessor level;
|
||||||
|
|
||||||
|
private final WeakContainmentMultiMap<LightListener> listenersBySection = new WeakContainmentMultiMap<>();
|
||||||
|
private final Set<TickingLightListener> tickingListeners = FlwUtil.createWeakHashSet();
|
||||||
|
|
||||||
public static LightUpdater get(LevelAccessor level) {
|
public static LightUpdater get(LevelAccessor level) {
|
||||||
if (LightUpdated.receivesLightUpdates(level)) {
|
if (LightUpdated.receivesLightUpdates(level)) {
|
||||||
|
@ -40,14 +41,7 @@ public class LightUpdater {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final LevelAccessor level;
|
|
||||||
|
|
||||||
private final Set<TickingLightListener> tickingLightListeners = FlwUtil.createWeakHashSet();
|
|
||||||
private final WeakContainmentMultiMap<LightListener> sections = new WeakContainmentMultiMap<>();
|
|
||||||
private final WeakContainmentMultiMap<LightListener> chunks = new WeakContainmentMultiMap<>();
|
|
||||||
|
|
||||||
public LightUpdater(LevelAccessor level) {
|
public LightUpdater(LevelAccessor level) {
|
||||||
taskExecutor = Backend.getTaskExecutor();
|
|
||||||
this.level = level;
|
this.level = level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +51,7 @@ public class LightUpdater {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tickSerial() {
|
private void tickSerial() {
|
||||||
for (TickingLightListener tickingLightListener : tickingLightListeners) {
|
for (TickingLightListener tickingLightListener : tickingListeners) {
|
||||||
if (tickingLightListener.tickLightListener()) {
|
if (tickingLightListener.tickLightListener()) {
|
||||||
addListener(tickingLightListener);
|
addListener(tickingLightListener);
|
||||||
}
|
}
|
||||||
|
@ -68,13 +62,13 @@ public class LightUpdater {
|
||||||
Queue<LightListener> listeners = new ConcurrentLinkedQueue<>();
|
Queue<LightListener> listeners = new ConcurrentLinkedQueue<>();
|
||||||
|
|
||||||
WorkGroup.builder()
|
WorkGroup.builder()
|
||||||
.addTasks(tickingLightListeners.stream(), listener -> {
|
.addTasks(tickingListeners.stream(), listener -> {
|
||||||
if (listener.tickLightListener()) {
|
if (listener.tickLightListener()) {
|
||||||
listeners.add(listener);
|
listeners.add(listener);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.onComplete(() -> listeners.forEach(this::addListener))
|
.onComplete(() -> listeners.forEach(this::addListener))
|
||||||
.execute(taskExecutor);
|
.execute(Backend.getTaskExecutor());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -84,12 +78,11 @@ public class LightUpdater {
|
||||||
*/
|
*/
|
||||||
public void addListener(LightListener listener) {
|
public void addListener(LightListener listener) {
|
||||||
if (listener instanceof TickingLightListener)
|
if (listener instanceof TickingLightListener)
|
||||||
tickingLightListeners.add(((TickingLightListener) listener));
|
tickingListeners.add(((TickingLightListener) listener));
|
||||||
|
|
||||||
ImmutableBox box = listener.getVolume();
|
ImmutableBox box = listener.getVolume();
|
||||||
|
|
||||||
LongSet sections = this.sections.getAndResetContainment(listener);
|
LongSet sections = this.listenersBySection.getAndResetContainment(listener);
|
||||||
LongSet chunks = this.chunks.getAndResetContainment(listener);
|
|
||||||
|
|
||||||
int minX = SectionPos.blockToSectionCoord(box.getMinX());
|
int minX = SectionPos.blockToSectionCoord(box.getMinX());
|
||||||
int minY = SectionPos.blockToSectionCoord(box.getMinY());
|
int minY = SectionPos.blockToSectionCoord(box.getMinY());
|
||||||
|
@ -99,75 +92,42 @@ public class LightUpdater {
|
||||||
int maxZ = SectionPos.blockToSectionCoord(box.getMaxZ());
|
int maxZ = SectionPos.blockToSectionCoord(box.getMaxZ());
|
||||||
|
|
||||||
for (int x = minX; x <= maxX; x++) {
|
for (int x = minX; x <= maxX; x++) {
|
||||||
for (int z = minZ; z <= maxZ; z++) {
|
|
||||||
for (int y = minY; y <= maxY; y++) {
|
for (int y = minY; y <= maxY; y++) {
|
||||||
|
for (int z = minZ; z <= maxZ; z++) {
|
||||||
long sectionPos = SectionPos.asLong(x, y, z);
|
long sectionPos = SectionPos.asLong(x, y, z);
|
||||||
this.sections.put(sectionPos, listener);
|
this.listenersBySection.put(sectionPos, listener);
|
||||||
sections.add(sectionPos);
|
sections.add(sectionPos);
|
||||||
}
|
}
|
||||||
long chunkPos = SectionPos.asLong(x, 0, z);
|
|
||||||
this.chunks.put(chunkPos, listener);
|
|
||||||
chunks.add(chunkPos);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeListener(LightListener listener) {
|
public void removeListener(LightListener listener) {
|
||||||
this.sections.remove(listener);
|
this.listenersBySection.remove(listener);
|
||||||
this.chunks.remove(listener);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatch light updates to all registered {@link LightListener}s.
|
* Dispatch light updates to all registered {@link LightListener}s.
|
||||||
* @param type The type of light that changed.
|
* @param type The type of light that changed.
|
||||||
* @param sectionPos A long representing the section position where light changed.
|
* @param pos The section position where light changed.
|
||||||
*/
|
*/
|
||||||
public void onLightUpdate(LightLayer type, long sectionPos) {
|
public void onLightUpdate(LightLayer type, SectionPos pos) {
|
||||||
Set<LightListener> set = sections.get(sectionPos);
|
Set<LightListener> listeners = listenersBySection.get(pos.asLong());
|
||||||
|
|
||||||
if (set == null || set.isEmpty()) return;
|
if (listeners == null || listeners.isEmpty()) return;
|
||||||
|
|
||||||
set.removeIf(LightListener::isListenerInvalid);
|
listeners.removeIf(LightListener::isInvalid);
|
||||||
|
|
||||||
ImmutableBox chunkBox = GridAlignedBB.from(SectionPos.of(sectionPos));
|
for (LightListener listener : listeners) {
|
||||||
|
listener.onLightUpdate(type, pos);
|
||||||
for (LightListener listener : set) {
|
|
||||||
listener.onLightUpdate(type, chunkBox);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatch light updates to all registered {@link LightListener}s
|
|
||||||
* when the server sends lighting data for an entire chunk.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void onLightPacket(int chunkX, int chunkZ) {
|
|
||||||
long chunkPos = SectionPos.asLong(chunkX, 0, chunkZ);
|
|
||||||
|
|
||||||
Set<LightListener> set = chunks.get(chunkPos);
|
|
||||||
|
|
||||||
if (set == null || set.isEmpty()) return;
|
|
||||||
|
|
||||||
set.removeIf(LightListener::isListenerInvalid);
|
|
||||||
|
|
||||||
for (LightListener listener : set) {
|
|
||||||
listener.onLightPacket(chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long blockToSection(BlockPos pos) {
|
|
||||||
return SectionPos.asLong(pos.getX(), pos.getY(), pos.getZ());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long sectionToChunk(long sectionPos) {
|
|
||||||
return sectionPos & 0xFFFFFFFFFFF_00000L;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Stream<ImmutableBox> getAllBoxes() {
|
public Stream<ImmutableBox> getAllBoxes() {
|
||||||
return chunks.stream().map(LightListener::getVolume);
|
return listenersBySection.stream().map(LightListener::getVolume);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return chunks.isEmpty();
|
return listenersBySection.isEmpty();
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,19 +1,20 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.lib.light;
|
||||||
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||||
|
import com.jozufozu.flywheel.lib.box.MutableBox;
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
|
|
||||||
public class LightVolume implements ImmutableBox, LightListener {
|
public class LightVolume implements ImmutableBox, LightListener {
|
||||||
|
|
||||||
protected final BlockAndTintGetter level;
|
protected final BlockAndTintGetter level;
|
||||||
protected final GridAlignedBB box = new GridAlignedBB();
|
protected final MutableBox box = new MutableBox();
|
||||||
protected MemoryBlock lightData;
|
protected MemoryBlock lightData;
|
||||||
|
|
||||||
public LightVolume(BlockAndTintGetter level, ImmutableBox sampleVolume) {
|
public LightVolume(BlockAndTintGetter level, ImmutableBox sampleVolume) {
|
||||||
|
@ -59,7 +60,7 @@ public class LightVolume implements ImmutableBox, LightListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isListenerInvalid() {
|
public boolean isInvalid() {
|
||||||
return lightData == null;
|
return lightData == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,10 +208,10 @@ public class LightVolume implements ImmutableBox, LightListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLightUpdate(LightLayer type, ImmutableBox changedVolume) {
|
public void onLightUpdate(LightLayer type, SectionPos pos) {
|
||||||
if (lightData == null) return;
|
if (lightData == null) return;
|
||||||
|
|
||||||
GridAlignedBB vol = changedVolume.copy();
|
MutableBox vol = MutableBox.from(pos);
|
||||||
if (!vol.intersects(getVolume())) return;
|
if (!vol.intersects(getVolume())) return;
|
||||||
vol.intersectAssign(getVolume()); // compute the region contained by us that has dirty lighting data.
|
vol.intersectAssign(getVolume()); // compute the region contained by us that has dirty lighting data.
|
||||||
|
|
||||||
|
@ -219,16 +220,4 @@ public class LightVolume implements ImmutableBox, LightListener {
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLightPacket(int chunkX, int chunkZ) {
|
|
||||||
if (lightData == null) return;
|
|
||||||
|
|
||||||
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
|
|
||||||
if (!changedVolume.intersects(getVolume())) return;
|
|
||||||
changedVolume.intersectAssign(getVolume()); // compute the region contained by us that has dirty lighting data.
|
|
||||||
|
|
||||||
copyLight(changedVolume);
|
|
||||||
markDirty();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.lib.light;
|
||||||
|
|
||||||
public interface TickingLightListener extends LightListener {
|
public interface TickingLightListener extends LightListener {
|
||||||
/**
|
/**
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.light;
|
package com.jozufozu.flywheel.lib.light;
|
||||||
|
|
||||||
import java.util.AbstractCollection;
|
import java.util.AbstractCollection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -24,7 +24,7 @@ public class WeakContainmentMultiMap<T> extends AbstractCollection<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a confusing function, but it maintains the internal state of the chunk/section maps.
|
* This is a confusing function, but it maintains the internal state of the section maps.
|
||||||
*
|
*
|
||||||
* <p>
|
* <p>
|
||||||
* First, uses the reverse lookup map to remove listener from all sets in the lookup map.<br>
|
* First, uses the reverse lookup map to remove listener from all sets in the lookup map.<br>
|
||||||
|
@ -32,7 +32,7 @@ public class WeakContainmentMultiMap<T> extends AbstractCollection<T> {
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param listener The listener to clean up.
|
* @param listener The listener to clean up.
|
||||||
* @return An empty set that should be populated with the chunks/sections the listener is contained in.
|
* @return An empty set that should be populated with the sections the listener is contained in.
|
||||||
*/
|
*/
|
||||||
public LongSet getAndResetContainment(T listener) {
|
public LongSet getAndResetContainment(T listener) {
|
||||||
LongSet containmentSet = reverse.computeIfAbsent(listener, $ -> new LongRBTreeSet());
|
LongSet containmentSet = reverse.computeIfAbsent(listener, $ -> new LongRBTreeSet());
|
|
@ -1,24 +0,0 @@
|
||||||
package com.jozufozu.flywheel.lib.util;
|
|
||||||
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
|
|
||||||
import net.minecraftforge.client.event.RenderLevelLastEvent;
|
|
||||||
|
|
||||||
public class RenderWork {
|
|
||||||
private static final Queue<Runnable> RUNS = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
public static void onRenderLevelLast(RenderLevelLastEvent event) {
|
|
||||||
while (!RUNS.isEmpty()) {
|
|
||||||
RUNS.remove()
|
|
||||||
.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queue work to be executed at the end of a frame
|
|
||||||
*/
|
|
||||||
public static void enqueue(Runnable run) {
|
|
||||||
RUNS.add(run);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package com.jozufozu.flywheel.mixin.light;
|
package com.jozufozu.flywheel.mixin;
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
import com.jozufozu.flywheel.lib.light.LightUpdater;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientChunkCache;
|
import net.minecraft.client.multiplayer.ClientChunkCache;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
@ -22,14 +22,12 @@ public abstract class LightUpdateMixin extends ChunkSource {
|
||||||
ClientLevel level;
|
ClientLevel level;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JUSTIFICATION: This method is called after a lighting tick once per subchunk where a
|
* JUSTIFICATION: This method is called after lighting updates are finished processing
|
||||||
* lighting change occurred that tick. On the client, Minecraft uses this method to inform
|
* per section where a lighting change occurred that frame. On the client, Minecraft
|
||||||
* the rendering system that it needs to redraw a chunk. It does all that work asynchronously,
|
* uses this method to inform the rendering system that it needs to redraw a chunk.
|
||||||
* and we should too.
|
|
||||||
*/
|
*/
|
||||||
@Inject(at = @At("HEAD"), method = "onLightUpdate")
|
@Inject(method = "onLightUpdate(Lnet/minecraft/world/level/LightLayer;Lnet/minecraft/core/SectionPos;)V", at = @At("HEAD"))
|
||||||
private void flywheel$onLightUpdate(LightLayer type, SectionPos pos, CallbackInfo ci) {
|
private void flywheel$onLightUpdate(LightLayer type, SectionPos pos, CallbackInfo ci) {
|
||||||
LightUpdater.get(level)
|
LightUpdater.get(level).onLightUpdate(type, pos);
|
||||||
.onLightUpdate(type, pos.asLong());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,32 +0,0 @@
|
||||||
package com.jozufozu.flywheel.mixin.light;
|
|
||||||
|
|
||||||
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.lib.util.RenderWork;
|
|
||||||
import com.jozufozu.flywheel.light.LightUpdater;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraft.client.multiplayer.ClientPacketListener;
|
|
||||||
import net.minecraft.network.protocol.game.ClientboundLightUpdatePacket;
|
|
||||||
|
|
||||||
@Mixin(ClientPacketListener.class)
|
|
||||||
public class NetworkLightUpdateMixin {
|
|
||||||
@Inject(at = @At("TAIL"), method = "handleLightUpdatePacket")
|
|
||||||
private void flywheel$onLightPacket(ClientboundLightUpdatePacket packet, CallbackInfo ci) {
|
|
||||||
RenderWork.enqueue(() -> {
|
|
||||||
ClientLevel level = Minecraft.getInstance().level;
|
|
||||||
|
|
||||||
if (level == null) return;
|
|
||||||
|
|
||||||
int chunkX = packet.getX();
|
|
||||||
int chunkZ = packet.getZ();
|
|
||||||
|
|
||||||
LightUpdater.get(level)
|
|
||||||
.onLightPacket(chunkX, chunkZ);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
package com.jozufozu.flywheel.util.box;
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface CoordinateConsumer {
|
|
||||||
void consume(int x, int y, int z);
|
|
||||||
}
|
|
|
@ -16,12 +16,12 @@ import com.jozufozu.flywheel.api.instancer.InstancerManager;
|
||||||
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
import com.jozufozu.flywheel.backend.instancing.AbstractInstance;
|
||||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||||
import com.jozufozu.flywheel.backend.instancing.effect.Effect;
|
import com.jozufozu.flywheel.backend.instancing.effect.Effect;
|
||||||
|
import com.jozufozu.flywheel.lib.box.ImmutableBox;
|
||||||
|
import com.jozufozu.flywheel.lib.box.MutableBox;
|
||||||
import com.jozufozu.flywheel.lib.model.Models;
|
import com.jozufozu.flywheel.lib.model.Models;
|
||||||
import com.jozufozu.flywheel.lib.struct.StructTypes;
|
import com.jozufozu.flywheel.lib.struct.StructTypes;
|
||||||
import com.jozufozu.flywheel.lib.struct.TransformedPart;
|
import com.jozufozu.flywheel.lib.struct.TransformedPart;
|
||||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||||
import com.jozufozu.flywheel.util.box.GridAlignedBB;
|
|
||||||
import com.jozufozu.flywheel.util.box.ImmutableBox;
|
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
@ -67,7 +67,7 @@ public class ExampleEffect implements Effect {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
this.targetPoint = targetPoint;
|
this.targetPoint = targetPoint;
|
||||||
this.blockPos = new BlockPos(targetPoint.x, targetPoint.y, targetPoint.z);
|
this.blockPos = new BlockPos(targetPoint.x, targetPoint.y, targetPoint.z);
|
||||||
this.volume = GridAlignedBB.from(this.blockPos);
|
this.volume = MutableBox.from(this.blockPos);
|
||||||
this.effects = new ArrayList<>(INSTANCE_COUNT);
|
this.effects = new ArrayList<>(INSTANCE_COUNT);
|
||||||
this.boids = new ArrayList<>(INSTANCE_COUNT);
|
this.boids = new ArrayList<>(INSTANCE_COUNT);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
"GlStateManagerMixin",
|
"GlStateManagerMixin",
|
||||||
"LevelRendererAccessor",
|
"LevelRendererAccessor",
|
||||||
"LevelRendererMixin",
|
"LevelRendererMixin",
|
||||||
|
"LightUpdateMixin",
|
||||||
"PausedPartialTickAccessor",
|
"PausedPartialTickAccessor",
|
||||||
"RenderTypeMixin",
|
"RenderTypeMixin",
|
||||||
"VertexFormatMixin",
|
"VertexFormatMixin",
|
||||||
|
@ -22,8 +23,6 @@
|
||||||
"instancemanage.InstanceAddMixin",
|
"instancemanage.InstanceAddMixin",
|
||||||
"instancemanage.InstanceRemoveMixin",
|
"instancemanage.InstanceRemoveMixin",
|
||||||
"instancemanage.InstanceUpdateMixin",
|
"instancemanage.InstanceUpdateMixin",
|
||||||
"light.LightUpdateMixin",
|
|
||||||
"light.NetworkLightUpdateMixin",
|
|
||||||
"matrix.Matrix3fAccessor",
|
"matrix.Matrix3fAccessor",
|
||||||
"matrix.Matrix4fAccessor",
|
"matrix.Matrix4fAccessor",
|
||||||
"matrix.PoseStackMixin"
|
"matrix.PoseStackMixin"
|
||||||
|
|
Loading…
Add table
Reference in a new issue