mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-23 11:27:54 +01:00
Merge remote-tracking branch 'upstream/1.20/dev' into feat/multi-loader-1.21
This commit is contained in:
commit
eb1c56e9ac
13 changed files with 452 additions and 131 deletions
|
@ -0,0 +1,5 @@
|
||||||
|
package dev.engine_room.flywheel.backend;
|
||||||
|
|
||||||
|
public class BackendDebugFlags {
|
||||||
|
public static boolean LIGHT_STORAGE_VIEW = false;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package dev.engine_room.flywheel.backend;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.chunk.DataLayer;
|
||||||
|
|
||||||
|
public interface SkyLightSectionStorageExtension {
|
||||||
|
@Nullable DataLayer flywheel$skyDataLayer(long section);
|
||||||
|
}
|
|
@ -23,6 +23,11 @@ public final class LightLut {
|
||||||
.set(z, index + 1);
|
.set(z, index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void prune() {
|
||||||
|
// Maybe this could be done better incrementally?
|
||||||
|
indices.prune((middle) -> middle.prune(IntLayer::prune));
|
||||||
|
}
|
||||||
|
|
||||||
public void remove(long section) {
|
public void remove(long section) {
|
||||||
final var x = SectionPos.x(section);
|
final var x = SectionPos.x(section);
|
||||||
final var y = SectionPos.y(section);
|
final var y = SectionPos.y(section);
|
||||||
|
@ -49,6 +54,11 @@ public final class LightLut {
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface Prune<T> {
|
||||||
|
boolean prune(T t);
|
||||||
|
}
|
||||||
|
|
||||||
public static final class Layer<T> {
|
public static final class Layer<T> {
|
||||||
private boolean hasBase = false;
|
private boolean hasBase = false;
|
||||||
private int base = 0;
|
private int base = 0;
|
||||||
|
@ -135,6 +145,69 @@ public final class LightLut {
|
||||||
return (T) out;
|
return (T) out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the layer is now empty.
|
||||||
|
*/
|
||||||
|
public boolean prune(Prune<T> inner) {
|
||||||
|
if (!hasBase) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prune the next layer before checking for leading/trailing zeros.
|
||||||
|
for (var i = 0; i < nextLayer.length; i++) {
|
||||||
|
var o = nextLayer[i];
|
||||||
|
if (o != null && inner.prune((T) o)) {
|
||||||
|
nextLayer[i] = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var leadingZeros = getLeadingZeros();
|
||||||
|
|
||||||
|
if (leadingZeros == nextLayer.length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var trailingZeros = getTrailingZeros();
|
||||||
|
|
||||||
|
if (leadingZeros == 0 && trailingZeros == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final var newIndices = new Object[nextLayer.length - leadingZeros - trailingZeros];
|
||||||
|
|
||||||
|
System.arraycopy(nextLayer, leadingZeros, newIndices, 0, newIndices.length);
|
||||||
|
nextLayer = newIndices;
|
||||||
|
base += leadingZeros;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getLeadingZeros() {
|
||||||
|
int out = 0;
|
||||||
|
|
||||||
|
for (Object index : nextLayer) {
|
||||||
|
if (index == null) {
|
||||||
|
out++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTrailingZeros() {
|
||||||
|
int out = 0;
|
||||||
|
|
||||||
|
for (int i = nextLayer.length - 1; i >= 0; i--) {
|
||||||
|
if (nextLayer[i] == null) {
|
||||||
|
out++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
private void resize(int length) {
|
private void resize(int length) {
|
||||||
final var newIndices = new Object[length];
|
final var newIndices = new Object[length];
|
||||||
System.arraycopy(nextLayer, 0, newIndices, 0, nextLayer.length);
|
System.arraycopy(nextLayer, 0, newIndices, 0, nextLayer.length);
|
||||||
|
@ -214,6 +287,61 @@ public final class LightLut {
|
||||||
indices[offset] = index;
|
indices[offset] = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@code true} if the layer is now empty.
|
||||||
|
*/
|
||||||
|
public boolean prune() {
|
||||||
|
if (!hasBase) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var leadingZeros = getLeadingZeros();
|
||||||
|
|
||||||
|
if (leadingZeros == indices.length) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
var trailingZeros = getTrailingZeros();
|
||||||
|
|
||||||
|
if (leadingZeros == 0 && trailingZeros == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final var newIndices = new int[indices.length - leadingZeros - trailingZeros];
|
||||||
|
|
||||||
|
System.arraycopy(indices, leadingZeros, newIndices, 0, newIndices.length);
|
||||||
|
indices = newIndices;
|
||||||
|
base += leadingZeros;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getTrailingZeros() {
|
||||||
|
int out = 0;
|
||||||
|
|
||||||
|
for (int i = indices.length - 1; i >= 0; i--) {
|
||||||
|
if (indices[i] == 0) {
|
||||||
|
out++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getLeadingZeros() {
|
||||||
|
int out = 0;
|
||||||
|
|
||||||
|
for (int index : indices) {
|
||||||
|
if (index == 0) {
|
||||||
|
out++;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
public void clear(int i) {
|
public void clear(int i) {
|
||||||
if (!hasBase) {
|
if (!hasBase) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -10,8 +10,11 @@ import dev.engine_room.flywheel.api.visual.Effect;
|
||||||
import dev.engine_room.flywheel.api.visual.EffectVisual;
|
import dev.engine_room.flywheel.api.visual.EffectVisual;
|
||||||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||||
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
|
import dev.engine_room.flywheel.api.visualization.VisualizationManager;
|
||||||
|
import dev.engine_room.flywheel.backend.BackendDebugFlags;
|
||||||
|
import dev.engine_room.flywheel.backend.SkyLightSectionStorageExtension;
|
||||||
import dev.engine_room.flywheel.backend.engine.indirect.StagingBuffer;
|
import dev.engine_room.flywheel.backend.engine.indirect.StagingBuffer;
|
||||||
import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer;
|
import dev.engine_room.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
|
import dev.engine_room.flywheel.backend.mixin.light.LightEngineAccessor;
|
||||||
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
|
import dev.engine_room.flywheel.lib.instance.InstanceTypes;
|
||||||
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
|
import dev.engine_room.flywheel.lib.instance.TransformedInstance;
|
||||||
import dev.engine_room.flywheel.lib.math.MoreMath;
|
import dev.engine_room.flywheel.lib.math.MoreMath;
|
||||||
|
@ -27,9 +30,10 @@ import it.unimi.dsi.fastutil.longs.LongSet;
|
||||||
import net.minecraft.client.renderer.LightTexture;
|
import net.minecraft.client.renderer.LightTexture;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
|
import net.minecraft.core.Vec3i;
|
||||||
import net.minecraft.world.level.LevelAccessor;
|
import net.minecraft.world.level.LevelAccessor;
|
||||||
import net.minecraft.world.level.LightLayer;
|
import net.minecraft.world.level.LightLayer;
|
||||||
import net.minecraft.world.level.lighting.LayerLightEventListener;
|
import net.minecraft.world.level.chunk.DataLayer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A managed arena of light sections for uploading to the GPU.
|
* A managed arena of light sections for uploading to the GPU.
|
||||||
|
@ -46,8 +50,6 @@ import net.minecraft.world.level.lighting.LayerLightEventListener;
|
||||||
* <p>Thus, each section occupies 5832 bytes.
|
* <p>Thus, each section occupies 5832 bytes.
|
||||||
*/
|
*/
|
||||||
public class LightStorage implements Effect {
|
public class LightStorage implements Effect {
|
||||||
public static boolean DEBUG = false;
|
|
||||||
|
|
||||||
public static final int BLOCKS_PER_SECTION = 18 * 18 * 18;
|
public static final int BLOCKS_PER_SECTION = 18 * 18 * 18;
|
||||||
public static final int LIGHT_SIZE_BYTES = BLOCKS_PER_SECTION;
|
public static final int LIGHT_SIZE_BYTES = BLOCKS_PER_SECTION;
|
||||||
public static final int SOLID_SIZE_BYTES = MoreMath.ceilingDiv(BLOCKS_PER_SECTION, Integer.SIZE) * Integer.BYTES;
|
public static final int SOLID_SIZE_BYTES = MoreMath.ceilingDiv(BLOCKS_PER_SECTION, Integer.SIZE) * Integer.BYTES;
|
||||||
|
@ -55,6 +57,9 @@ public class LightStorage implements Effect {
|
||||||
private static final int DEFAULT_ARENA_CAPACITY_SECTIONS = 64;
|
private static final int DEFAULT_ARENA_CAPACITY_SECTIONS = 64;
|
||||||
private static final int INVALID_SECTION = -1;
|
private static final int INVALID_SECTION = -1;
|
||||||
|
|
||||||
|
private static final ConstantDataLayer EMPTY_BLOCK_DATA = new ConstantDataLayer(0);
|
||||||
|
private static final ConstantDataLayer EMPTY_SKY_DATA = new ConstantDataLayer(15);
|
||||||
|
|
||||||
private final LevelAccessor level;
|
private final LevelAccessor level;
|
||||||
private final LightLut lut;
|
private final LightLut lut;
|
||||||
private final CpuArena arena;
|
private final CpuArena arena;
|
||||||
|
@ -102,12 +107,12 @@ public class LightStorage implements Effect {
|
||||||
|
|
||||||
public <C> Plan<C> createFramePlan() {
|
public <C> Plan<C> createFramePlan() {
|
||||||
return SimplePlan.of(() -> {
|
return SimplePlan.of(() -> {
|
||||||
if (DEBUG != isDebugOn) {
|
if (BackendDebugFlags.LIGHT_STORAGE_VIEW != isDebugOn) {
|
||||||
var visualizationManager = VisualizationManager.get(level);
|
var visualizationManager = VisualizationManager.get(level);
|
||||||
|
|
||||||
// Really should be non-null, but just in case.
|
// Really should be non-null, but just in case.
|
||||||
if (visualizationManager != null) {
|
if (visualizationManager != null) {
|
||||||
if (DEBUG) {
|
if (BackendDebugFlags.LIGHT_STORAGE_VIEW) {
|
||||||
visualizationManager.effects()
|
visualizationManager.effects()
|
||||||
.queueAdd(this);
|
.queueAdd(this);
|
||||||
} else {
|
} else {
|
||||||
|
@ -115,7 +120,7 @@ public class LightStorage implements Effect {
|
||||||
.queueRemove(this);
|
.queueRemove(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isDebugOn = DEBUG;
|
isDebugOn = BackendDebugFlags.LIGHT_STORAGE_VIEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updatedSections.isEmpty() && requestedSections == null) {
|
if (updatedSections.isEmpty() && requestedSections == null) {
|
||||||
|
@ -165,6 +170,8 @@ public class LightStorage implements Effect {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean anyRemoved = false;
|
||||||
|
|
||||||
var entries = section2ArenaIndex.long2IntEntrySet();
|
var entries = section2ArenaIndex.long2IntEntrySet();
|
||||||
var it = entries.iterator();
|
var it = entries.iterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
|
@ -175,8 +182,14 @@ public class LightStorage implements Effect {
|
||||||
arena.free(entry.getIntValue());
|
arena.free(entry.getIntValue());
|
||||||
endTrackingSection(section);
|
endTrackingSection(section);
|
||||||
it.remove();
|
it.remove();
|
||||||
|
anyRemoved = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (anyRemoved) {
|
||||||
|
lut.prune();
|
||||||
|
needsLutRebuild = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void beginTrackingSection(long section, int index) {
|
private void beginTrackingSection(long section, int index) {
|
||||||
|
@ -194,11 +207,6 @@ public class LightStorage implements Effect {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void collectSection(long section) {
|
public void collectSection(long section) {
|
||||||
var lightEngine = level.getLightEngine();
|
|
||||||
|
|
||||||
var blockLight = lightEngine.getLayerListener(LightLayer.BLOCK);
|
|
||||||
var skyLight = lightEngine.getLayerListener(LightLayer.SKY);
|
|
||||||
|
|
||||||
int index = indexForSection(section);
|
int index = indexForSection(section);
|
||||||
|
|
||||||
changed.set(index);
|
changed.set(index);
|
||||||
|
@ -210,21 +218,21 @@ public class LightStorage implements Effect {
|
||||||
|
|
||||||
collectSolidData(ptr, section);
|
collectSolidData(ptr, section);
|
||||||
|
|
||||||
collectCenter(blockLight, skyLight, ptr, section);
|
collectCenter(ptr, section);
|
||||||
|
|
||||||
for (SectionEdge i : SectionEdge.values()) {
|
for (SectionEdge i : SectionEdge.values()) {
|
||||||
collectYZPlane(blockLight, skyLight, ptr, SectionPos.offset(section, i.sectionOffset, 0, 0), i);
|
collectYZPlane(ptr, SectionPos.offset(section, i.sectionOffset, 0, 0), i);
|
||||||
collectXZPlane(blockLight, skyLight, ptr, SectionPos.offset(section, 0, i.sectionOffset, 0), i);
|
collectXZPlane(ptr, SectionPos.offset(section, 0, i.sectionOffset, 0), i);
|
||||||
collectXYPlane(blockLight, skyLight, ptr, SectionPos.offset(section, 0, 0, i.sectionOffset), i);
|
collectXYPlane(ptr, SectionPos.offset(section, 0, 0, i.sectionOffset), i);
|
||||||
|
|
||||||
for (SectionEdge j : SectionEdge.values()) {
|
for (SectionEdge j : SectionEdge.values()) {
|
||||||
collectXStrip(blockLight, skyLight, ptr, SectionPos.offset(section, 0, i.sectionOffset, j.sectionOffset), i, j);
|
collectXStrip(ptr, SectionPos.offset(section, 0, i.sectionOffset, j.sectionOffset), i, j);
|
||||||
collectYStrip(blockLight, skyLight, ptr, SectionPos.offset(section, i.sectionOffset, 0, j.sectionOffset), i, j);
|
collectYStrip(ptr, SectionPos.offset(section, i.sectionOffset, 0, j.sectionOffset), i, j);
|
||||||
collectZStrip(blockLight, skyLight, ptr, SectionPos.offset(section, i.sectionOffset, j.sectionOffset, 0), i, j);
|
collectZStrip(ptr, SectionPos.offset(section, i.sectionOffset, j.sectionOffset, 0), i, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collectCorners(blockLight, skyLight, ptr, section);
|
collectCorners(ptr, section);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectSolidData(long ptr, long section) {
|
private void collectSolidData(long ptr, long section) {
|
||||||
|
@ -259,64 +267,59 @@ public class LightStorage implements Effect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeSolid(long ptr, int index, boolean blockValid) {
|
private DataLayer getSkyData(long section) {
|
||||||
if (!blockValid) {
|
var sky = level.getLightEngine()
|
||||||
return;
|
.getLayerListener(LightLayer.SKY);
|
||||||
|
var skyStorage = (SkyLightSectionStorageExtension) ((LightEngineAccessor<?, ?>) sky).flywheel$storage();
|
||||||
|
|
||||||
|
var out = skyStorage.flywheel$skyDataLayer(section);
|
||||||
|
|
||||||
|
if (out == null) {
|
||||||
|
return EMPTY_SKY_DATA;
|
||||||
}
|
}
|
||||||
int intIndex = index / Integer.SIZE;
|
|
||||||
int bitIndex = index % Integer.SIZE;
|
|
||||||
|
|
||||||
long offset = intIndex * Integer.BYTES;
|
return out;
|
||||||
|
|
||||||
int bitField = MemoryUtil.memGetInt(ptr + offset);
|
|
||||||
bitField |= 1 << bitIndex;
|
|
||||||
|
|
||||||
MemoryUtil.memPutInt(ptr + offset, bitField);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectXStrip(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section, SectionEdge y, SectionEdge z) {
|
private DataLayer getBlockData(long section) {
|
||||||
var pos = SectionPos.of(section);
|
var out = ((LightEngineAccessor<?, ?>) level.getLightEngine()
|
||||||
var blockData = blockLight.getDataLayerData(pos);
|
.getLayerListener(LightLayer.BLOCK)).flywheel$storage()
|
||||||
var skyData = skyLight.getDataLayerData(pos);
|
.getDataLayerData(section);
|
||||||
if (blockData == null || skyData == null) {
|
|
||||||
return;
|
if (out == null) {
|
||||||
|
return EMPTY_BLOCK_DATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectXStrip(long ptr, long section, SectionEdge y, SectionEdge z) {
|
||||||
|
var blockData = getBlockData(section);
|
||||||
|
var skyData = getSkyData(section);
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
write(ptr, x, y.relative, z.relative, blockData.get(x, y.pos, z.pos), skyData.get(x, y.pos, z.pos));
|
write(ptr, x, y.relative, z.relative, blockData.get(x, y.pos, z.pos), skyData.get(x, y.pos, z.pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectYStrip(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section, SectionEdge x, SectionEdge z) {
|
private void collectYStrip(long ptr, long section, SectionEdge x, SectionEdge z) {
|
||||||
var pos = SectionPos.of(section);
|
var blockData = getBlockData(section);
|
||||||
var blockData = blockLight.getDataLayerData(pos);
|
var skyData = getSkyData(section);
|
||||||
var skyData = skyLight.getDataLayerData(pos);
|
|
||||||
if (blockData == null || skyData == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int y = 0; y < 16; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
write(ptr, x.relative, y, z.relative, blockData.get(x.pos, y, z.pos), skyData.get(x.pos, y, z.pos));
|
write(ptr, x.relative, y, z.relative, blockData.get(x.pos, y, z.pos), skyData.get(x.pos, y, z.pos));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectZStrip(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section, SectionEdge x, SectionEdge y) {
|
private void collectZStrip(long ptr, long section, SectionEdge x, SectionEdge y) {
|
||||||
var pos = SectionPos.of(section);
|
var blockData = getBlockData(section);
|
||||||
var blockData = blockLight.getDataLayerData(pos);
|
var skyData = getSkyData(section);
|
||||||
var skyData = skyLight.getDataLayerData(pos);
|
|
||||||
if (blockData == null || skyData == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
write(ptr, x.relative, y.relative, z, blockData.get(x.pos, y.pos, z), skyData.get(x.pos, y.pos, z));
|
write(ptr, x.relative, y.relative, z, blockData.get(x.pos, y.pos, z), skyData.get(x.pos, y.pos, z));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectYZPlane(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section, SectionEdge x) {
|
private void collectYZPlane(long ptr, long section, SectionEdge x) {
|
||||||
var pos = SectionPos.of(section);
|
var blockData = getBlockData(section);
|
||||||
var blockData = blockLight.getDataLayerData(pos);
|
var skyData = getSkyData(section);
|
||||||
var skyData = skyLight.getDataLayerData(pos);
|
|
||||||
if (blockData == null || skyData == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int y = 0; y < 16; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
write(ptr, x.relative, y, z, blockData.get(x.pos, y, z), skyData.get(x.pos, y, z));
|
write(ptr, x.relative, y, z, blockData.get(x.pos, y, z), skyData.get(x.pos, y, z));
|
||||||
|
@ -324,13 +327,9 @@ public class LightStorage implements Effect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectXZPlane(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section, SectionEdge y) {
|
private void collectXZPlane(long ptr, long section, SectionEdge y) {
|
||||||
var pos = SectionPos.of(section);
|
var blockData = getBlockData(section);
|
||||||
var blockData = blockLight.getDataLayerData(pos);
|
var skyData = getSkyData(section);
|
||||||
var skyData = skyLight.getDataLayerData(pos);
|
|
||||||
if (blockData == null || skyData == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
write(ptr, x, y.relative, z, blockData.get(x, y.pos, z), skyData.get(x, y.pos, z));
|
write(ptr, x, y.relative, z, blockData.get(x, y.pos, z), skyData.get(x, y.pos, z));
|
||||||
|
@ -338,13 +337,9 @@ public class LightStorage implements Effect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectXYPlane(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section, SectionEdge z) {
|
private void collectXYPlane(long ptr, long section, SectionEdge z) {
|
||||||
var pos = SectionPos.of(section);
|
var blockData = getBlockData(section);
|
||||||
var blockData = blockLight.getDataLayerData(pos);
|
var skyData = getSkyData(section);
|
||||||
var skyData = skyLight.getDataLayerData(pos);
|
|
||||||
if (blockData == null || skyData == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int y = 0; y < 16; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
write(ptr, x, y, z.relative, blockData.get(x, y, z.pos), skyData.get(x, y, z.pos));
|
write(ptr, x, y, z.relative, blockData.get(x, y, z.pos), skyData.get(x, y, z.pos));
|
||||||
|
@ -352,13 +347,9 @@ public class LightStorage implements Effect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectCenter(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section) {
|
private void collectCenter(long ptr, long section) {
|
||||||
var pos = SectionPos.of(section);
|
var blockData = getBlockData(section);
|
||||||
var blockData = blockLight.getDataLayerData(pos);
|
var skyData = getSkyData(section);
|
||||||
var skyData = skyLight.getDataLayerData(pos);
|
|
||||||
if (blockData == null || skyData == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int y = 0; y < 16; y++) {
|
for (int y = 0; y < 16; y++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (int z = 0; z < 16; z++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (int x = 0; x < 16; x++) {
|
||||||
|
@ -368,7 +359,12 @@ public class LightStorage implements Effect {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void collectCorners(LayerLightEventListener blockLight, LayerLightEventListener skyLight, long ptr, long section) {
|
private void collectCorners(long ptr, long section) {
|
||||||
|
var lightEngine = level.getLightEngine();
|
||||||
|
|
||||||
|
var blockLight = lightEngine.getLayerListener(LightLayer.BLOCK);
|
||||||
|
var skyLight = lightEngine.getLayerListener(LightLayer.SKY);
|
||||||
|
|
||||||
var blockPos = new BlockPos.MutableBlockPos();
|
var blockPos = new BlockPos.MutableBlockPos();
|
||||||
int xMin = SectionPos.sectionToBlockCoord(SectionPos.x(section));
|
int xMin = SectionPos.sectionToBlockCoord(SectionPos.x(section));
|
||||||
int yMin = SectionPos.sectionToBlockCoord(SectionPos.y(section));
|
int yMin = SectionPos.sectionToBlockCoord(SectionPos.y(section));
|
||||||
|
@ -485,8 +481,10 @@ public class LightStorage implements Effect {
|
||||||
public class DebugVisual implements EffectVisual<LightStorage>, SimpleDynamicVisual {
|
public class DebugVisual implements EffectVisual<LightStorage>, SimpleDynamicVisual {
|
||||||
|
|
||||||
private final InstanceRecycler<TransformedInstance> boxes;
|
private final InstanceRecycler<TransformedInstance> boxes;
|
||||||
|
private final Vec3i renderOrigin;
|
||||||
|
|
||||||
public DebugVisual(VisualizationContext ctx, float partialTick) {
|
public DebugVisual(VisualizationContext ctx, float partialTick) {
|
||||||
|
renderOrigin = ctx.renderOrigin();
|
||||||
boxes = new InstanceRecycler<>(() -> ctx.instancerProvider()
|
boxes = new InstanceRecycler<>(() -> ctx.instancerProvider()
|
||||||
.instancer(InstanceTypes.TRANSFORMED, HitboxComponent.BOX_MODEL)
|
.instancer(InstanceTypes.TRANSFORMED, HitboxComponent.BOX_MODEL)
|
||||||
.createInstance());
|
.createInstance());
|
||||||
|
@ -505,15 +503,15 @@ public class LightStorage implements Effect {
|
||||||
private void setupSectionBoxes() {
|
private void setupSectionBoxes() {
|
||||||
section2ArenaIndex.keySet()
|
section2ArenaIndex.keySet()
|
||||||
.forEach(l -> {
|
.forEach(l -> {
|
||||||
var x = SectionPos.x(l);
|
var x = SectionPos.x(l) * 16 - renderOrigin.getX();
|
||||||
var y = SectionPos.y(l);
|
var y = SectionPos.y(l) * 16 - renderOrigin.getY();
|
||||||
var z = SectionPos.z(l);
|
var z = SectionPos.z(l) * 16 - renderOrigin.getZ();
|
||||||
|
|
||||||
var instance = boxes.get();
|
var instance = boxes.get();
|
||||||
|
|
||||||
instance.setIdentityTransform()
|
instance.setIdentityTransform()
|
||||||
.scale(16)
|
|
||||||
.translate(x, y, z)
|
.translate(x, y, z)
|
||||||
|
.scale(16)
|
||||||
.color(255, 255, 0)
|
.color(255, 255, 0)
|
||||||
.light(LightTexture.FULL_BRIGHT)
|
.light(LightTexture.FULL_BRIGHT)
|
||||||
.setChanged();
|
.setChanged();
|
||||||
|
@ -526,6 +524,14 @@ public class LightStorage implements Effect {
|
||||||
var base1 = first.base();
|
var base1 = first.base();
|
||||||
var size1 = first.size();
|
var size1 = first.size();
|
||||||
|
|
||||||
|
float debug1 = base1 * 16 - renderOrigin.getY();
|
||||||
|
|
||||||
|
float min2 = Float.POSITIVE_INFINITY;
|
||||||
|
float max2 = Float.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
|
float min3 = Float.POSITIVE_INFINITY;
|
||||||
|
float max3 = Float.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
for (int y = 0; y < size1; y++) {
|
for (int y = 0; y < size1; y++) {
|
||||||
var second = first.getRaw(y);
|
var second = first.getRaw(y);
|
||||||
|
|
||||||
|
@ -536,6 +542,16 @@ public class LightStorage implements Effect {
|
||||||
var base2 = second.base();
|
var base2 = second.base();
|
||||||
var size2 = second.size();
|
var size2 = second.size();
|
||||||
|
|
||||||
|
float y2 = (base1 + y) * 16 - renderOrigin.getY() + 7.5f;
|
||||||
|
|
||||||
|
min2 = Math.min(min2, base2);
|
||||||
|
max2 = Math.max(max2, base2 + size2);
|
||||||
|
|
||||||
|
float minLocal3 = Float.POSITIVE_INFINITY;
|
||||||
|
float maxLocal3 = Float.NEGATIVE_INFINITY;
|
||||||
|
|
||||||
|
float debug2 = base2 * 16 - renderOrigin.getX();
|
||||||
|
|
||||||
for (int x = 0; x < size2; x++) {
|
for (int x = 0; x < size2; x++) {
|
||||||
var third = second.getRaw(x);
|
var third = second.getRaw(x);
|
||||||
|
|
||||||
|
@ -546,55 +562,43 @@ public class LightStorage implements Effect {
|
||||||
var base3 = third.base();
|
var base3 = third.base();
|
||||||
var size3 = third.size();
|
var size3 = third.size();
|
||||||
|
|
||||||
|
float x2 = (base2 + x) * 16 - renderOrigin.getX() + 7.5f;
|
||||||
|
|
||||||
|
min3 = Math.min(min3, base3);
|
||||||
|
max3 = Math.max(max3, base3 + size3);
|
||||||
|
|
||||||
|
minLocal3 = Math.min(minLocal3, base3);
|
||||||
|
maxLocal3 = Math.max(maxLocal3, base3 + size3);
|
||||||
|
|
||||||
|
float debug3 = base3 * 16 - renderOrigin.getZ();
|
||||||
|
|
||||||
for (int z = 0; z < size3; z++) {
|
for (int z = 0; z < size3; z++) {
|
||||||
float x1 = base2 * 16;
|
|
||||||
float y1 = base1 * 16;
|
|
||||||
float z1 = base3 * 16;
|
|
||||||
|
|
||||||
float x2 = (base2 + x) * 16 + 7.5f;
|
|
||||||
float y2 = (base1 + y) * 16 + 7.5f;
|
|
||||||
float z2 = (base3 + z) * 16 + 7.5f;
|
|
||||||
boxes.get()
|
boxes.get()
|
||||||
.setIdentityTransform()
|
.setIdentityTransform()
|
||||||
.translate(x1, y2, z2)
|
.translate(x2, y2, debug3)
|
||||||
.scale(size2 * 16, 1, 1)
|
|
||||||
.color(255, 0, 0)
|
|
||||||
.light(LightTexture.FULL_BRIGHT)
|
|
||||||
.setChanged();
|
|
||||||
|
|
||||||
boxes.get()
|
|
||||||
.setIdentityTransform()
|
|
||||||
.translate(x2, y1, z2)
|
|
||||||
.scale(1, size1 * 16, 1)
|
|
||||||
.color(0, 255, 0)
|
|
||||||
.light(LightTexture.FULL_BRIGHT)
|
|
||||||
.setChanged();
|
|
||||||
|
|
||||||
boxes.get()
|
|
||||||
.setIdentityTransform()
|
|
||||||
.translate(x2, y2, z1)
|
|
||||||
.scale(1, 1, size3 * 16)
|
.scale(1, 1, size3 * 16)
|
||||||
.color(0, 0, 255)
|
.color(0, 0, 255)
|
||||||
.light(LightTexture.FULL_BRIGHT)
|
.light(LightTexture.FULL_BRIGHT)
|
||||||
.setChanged();
|
.setChanged();
|
||||||
|
|
||||||
if (third.getRaw(z) == 0) {
|
|
||||||
float x3 = (base2 + x) * 16 + 6f;
|
|
||||||
float y3 = (base1 + y) * 16 + 6f;
|
|
||||||
float z3 = (base3 + z) * 16 + 6f;
|
|
||||||
|
|
||||||
// Freely representable section that is not filled.
|
|
||||||
boxes.get()
|
|
||||||
.setIdentityTransform()
|
|
||||||
.translate(x3, y3, z3)
|
|
||||||
.scale(4)
|
|
||||||
.color(0, 255, 255)
|
|
||||||
.light(LightTexture.FULL_BRIGHT)
|
|
||||||
.setChanged();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boxes.get()
|
||||||
|
.setIdentityTransform()
|
||||||
|
.translate(debug2, y2, minLocal3 * 16 - renderOrigin.getZ())
|
||||||
|
.scale(size2 * 16, 1, (maxLocal3 - minLocal3) * 16)
|
||||||
|
.color(255, 0, 0)
|
||||||
|
.light(LightTexture.FULL_BRIGHT)
|
||||||
|
.setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boxes.get()
|
||||||
|
.setIdentityTransform()
|
||||||
|
.translate(min2 * 16 - renderOrigin.getX(), debug1, min3 * 16 - renderOrigin.getZ())
|
||||||
|
.scale((max2 - min2) * 16, size1 * 16, (max3 - min3) * 16)
|
||||||
|
.color(0, 255, 0)
|
||||||
|
.light(LightTexture.FULL_BRIGHT)
|
||||||
|
.setChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -607,4 +611,17 @@ public class LightStorage implements Effect {
|
||||||
boxes.delete();
|
boxes.delete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class ConstantDataLayer extends DataLayer {
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private ConstantDataLayer(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int get(int x, int y, int z) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package dev.engine_room.flywheel.backend.mixin.light;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
import net.minecraft.world.level.lighting.DataLayerStorageMap;
|
||||||
|
import net.minecraft.world.level.lighting.LayerLightSectionStorage;
|
||||||
|
import net.minecraft.world.level.lighting.LightEngine;
|
||||||
|
|
||||||
|
@Mixin(LightEngine.class)
|
||||||
|
public interface LightEngineAccessor<M extends DataLayerStorageMap<M>, S extends LayerLightSectionStorage<M>> {
|
||||||
|
@Accessor("storage")
|
||||||
|
S flywheel$storage();
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package dev.engine_room.flywheel.backend.mixin.light;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
|
||||||
|
|
||||||
|
@Mixin(targets = "net.minecraft.world.level.lighting.SkyLightSectionStorage.SkyDataLayerStorageMap")
|
||||||
|
public interface SkyDataLayerStorageMapAccessor {
|
||||||
|
@Accessor("currentLowestY")
|
||||||
|
int flywheel$currentLowestY();
|
||||||
|
|
||||||
|
@Accessor("topSections")
|
||||||
|
Long2IntOpenHashMap flywheel$topSections();
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package dev.engine_room.flywheel.backend.mixin.light;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.backend.SkyLightSectionStorageExtension;
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.core.SectionPos;
|
||||||
|
import net.minecraft.world.level.chunk.DataLayer;
|
||||||
|
import net.minecraft.world.level.lighting.LayerLightSectionStorage;
|
||||||
|
import net.minecraft.world.level.lighting.SkyLightSectionStorage;
|
||||||
|
|
||||||
|
@Mixin(SkyLightSectionStorage.class)
|
||||||
|
public abstract class SkyLightSectionStorageMixin extends LayerLightSectionStorage implements SkyLightSectionStorageExtension {
|
||||||
|
protected SkyLightSectionStorageMixin() {
|
||||||
|
super(null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Nullable
|
||||||
|
public DataLayer flywheel$skyDataLayer(long section) {
|
||||||
|
// Logic copied from SkyLightSectionStorage#getLightValue, but here we directly return the DataLayer
|
||||||
|
|
||||||
|
long l = section;
|
||||||
|
int i = SectionPos.y(l);
|
||||||
|
SkyDataLayerStorageMapAccessor skyDataLayerStorageMap = (SkyDataLayerStorageMapAccessor) this.visibleSectionData;
|
||||||
|
int j = skyDataLayerStorageMap.flywheel$topSections()
|
||||||
|
.get(SectionPos.getZeroNode(l));
|
||||||
|
if (j != skyDataLayerStorageMap.flywheel$currentLowestY() && i < j) {
|
||||||
|
DataLayer dataLayer = this.getDataLayerData(l);
|
||||||
|
if (dataLayer == null) {
|
||||||
|
for (; dataLayer == null; dataLayer = this.getDataLayerData(l)) {
|
||||||
|
if (++i >= j) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
l = SectionPos.offset(l, Direction.UP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return dataLayer;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,10 @@
|
||||||
"GlStateManagerMixin",
|
"GlStateManagerMixin",
|
||||||
"LevelRendererAccessor",
|
"LevelRendererAccessor",
|
||||||
"OptionsMixin",
|
"OptionsMixin",
|
||||||
"RenderSystemMixin"
|
"RenderSystemMixin",
|
||||||
|
"light.LightEngineAccessor",
|
||||||
|
"light.SkyDataLayerStorageMapAccessor",
|
||||||
|
"light.SkyLightSectionStorageMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
package dev.engine_room.flywheel.lib.task;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.api.task.Plan;
|
||||||
|
import dev.engine_room.flywheel.api.task.TaskExecutor;
|
||||||
|
import dev.engine_room.flywheel.lib.task.functional.BooleanSupplierWithContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Executes one plan or another, depending on a dynamically evaluated condition.
|
||||||
|
*
|
||||||
|
* @param condition The condition to branch on.
|
||||||
|
* @param onTrue The plan to execute if the condition is true.
|
||||||
|
* @param <C> The type of the context object.
|
||||||
|
*/
|
||||||
|
public record ConditionalPlan<C>(BooleanSupplierWithContext<C> condition,
|
||||||
|
Plan<C> onTrue) implements SimplyComposedPlan<C> {
|
||||||
|
public static <C> Builder<C> on(BooleanSupplierWithContext<C> condition) {
|
||||||
|
return new Builder<>(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <C> Builder<C> on(BooleanSupplierWithContext.Ignored<C> condition) {
|
||||||
|
return new Builder<>(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(TaskExecutor taskExecutor, C context, Runnable onCompletion) {
|
||||||
|
if (condition.getAsBoolean(context)) {
|
||||||
|
onTrue.execute(taskExecutor, context, onCompletion);
|
||||||
|
} else {
|
||||||
|
onCompletion.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final class Builder<C> {
|
||||||
|
private final BooleanSupplierWithContext<C> condition;
|
||||||
|
|
||||||
|
public Builder(BooleanSupplierWithContext<C> condition) {
|
||||||
|
this.condition = condition;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConditionalPlan<C> then(Plan<C> onTrue) {
|
||||||
|
return new ConditionalPlan<>(condition, onTrue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package dev.engine_room.flywheel.impl;
|
||||||
|
|
||||||
|
public class ImplDebugFlags {
|
||||||
|
/**
|
||||||
|
* Debug flag to globally turn beginFrame/tick off.
|
||||||
|
*/
|
||||||
|
public static boolean PAUSE_UPDATES = false;
|
||||||
|
}
|
|
@ -15,6 +15,8 @@ import dev.engine_room.flywheel.api.visual.ShaderLightVisual;
|
||||||
import dev.engine_room.flywheel.api.visual.TickableVisual;
|
import dev.engine_room.flywheel.api.visual.TickableVisual;
|
||||||
import dev.engine_room.flywheel.api.visual.Visual;
|
import dev.engine_room.flywheel.api.visual.Visual;
|
||||||
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
import dev.engine_room.flywheel.api.visualization.VisualizationContext;
|
||||||
|
import dev.engine_room.flywheel.impl.ImplDebugFlags;
|
||||||
|
import dev.engine_room.flywheel.lib.task.ConditionalPlan;
|
||||||
import dev.engine_room.flywheel.lib.task.ForEachPlan;
|
import dev.engine_room.flywheel.lib.task.ForEachPlan;
|
||||||
import dev.engine_room.flywheel.lib.task.NestedPlan;
|
import dev.engine_room.flywheel.lib.task.NestedPlan;
|
||||||
import dev.engine_room.flywheel.lib.task.PlanMap;
|
import dev.engine_room.flywheel.lib.task.PlanMap;
|
||||||
|
@ -42,11 +44,16 @@ public abstract class Storage<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Plan<DynamicVisual.Context> framePlan() {
|
public Plan<DynamicVisual.Context> framePlan() {
|
||||||
return NestedPlan.of(dynamicVisuals, lightUpdatedVisuals.plan(), ForEachPlan.of(() -> simpleDynamicVisuals, SimpleDynamicVisual::beginFrame));
|
var update = ConditionalPlan.<DynamicVisual.Context>on(() -> !ImplDebugFlags.PAUSE_UPDATES)
|
||||||
|
.then(NestedPlan.of(dynamicVisuals, ForEachPlan.of(() -> simpleDynamicVisuals, SimpleDynamicVisual::beginFrame)));
|
||||||
|
|
||||||
|
// Do light updates regardless.
|
||||||
|
return NestedPlan.of(lightUpdatedVisuals.plan(), update);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Plan<TickableVisual.Context> tickPlan() {
|
public Plan<TickableVisual.Context> tickPlan() {
|
||||||
return NestedPlan.of(tickableVisuals, ForEachPlan.of(() -> simpleTickableVisuals, SimpleTickableVisual::tick));
|
return ConditionalPlan.<TickableVisual.Context>on(() -> !ImplDebugFlags.PAUSE_UPDATES)
|
||||||
|
.then(NestedPlan.of(tickableVisuals, ForEachPlan.of(() -> simpleTickableVisuals, SimpleTickableVisual::tick)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public LightUpdatedVisualStorage lightUpdatedVisuals() {
|
public LightUpdatedVisualStorage lightUpdatedVisuals() {
|
||||||
|
|
|
@ -8,9 +8,9 @@ import com.mojang.brigadier.context.CommandContext;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.backend.Backend;
|
import dev.engine_room.flywheel.api.backend.Backend;
|
||||||
import dev.engine_room.flywheel.api.backend.BackendManager;
|
import dev.engine_room.flywheel.api.backend.BackendManager;
|
||||||
|
import dev.engine_room.flywheel.backend.BackendDebugFlags;
|
||||||
import dev.engine_room.flywheel.backend.compile.LightSmoothness;
|
import dev.engine_room.flywheel.backend.compile.LightSmoothness;
|
||||||
import dev.engine_room.flywheel.backend.compile.PipelineCompiler;
|
import dev.engine_room.flywheel.backend.compile.PipelineCompiler;
|
||||||
import dev.engine_room.flywheel.backend.engine.LightStorage;
|
|
||||||
import dev.engine_room.flywheel.backend.engine.uniform.DebugMode;
|
import dev.engine_room.flywheel.backend.engine.uniform.DebugMode;
|
||||||
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
|
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
|
||||||
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
|
import net.fabricmc.fabric.api.client.command.v2.ClientCommandManager;
|
||||||
|
@ -179,12 +179,24 @@ public final class FlwCommands {
|
||||||
debug.then(ClientCommandManager.literal("lightSections")
|
debug.then(ClientCommandManager.literal("lightSections")
|
||||||
.then(ClientCommandManager.literal("on")
|
.then(ClientCommandManager.literal("on")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
LightStorage.DEBUG = true;
|
BackendDebugFlags.LIGHT_STORAGE_VIEW = true;
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
}))
|
}))
|
||||||
.then(ClientCommandManager.literal("off")
|
.then(ClientCommandManager.literal("off")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
LightStorage.DEBUG = false;
|
BackendDebugFlags.LIGHT_STORAGE_VIEW = false;
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
|
})));
|
||||||
|
|
||||||
|
debug.then(ClientCommandManager.literal("pauseUpdates")
|
||||||
|
.then(ClientCommandManager.literal("on")
|
||||||
|
.executes(context -> {
|
||||||
|
ImplDebugFlags.PAUSE_UPDATES = true;
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
|
}))
|
||||||
|
.then(ClientCommandManager.literal("off")
|
||||||
|
.executes(context -> {
|
||||||
|
ImplDebugFlags.PAUSE_UPDATES = false;
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
|
|
@ -6,9 +6,9 @@ import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.backend.Backend;
|
import dev.engine_room.flywheel.api.backend.Backend;
|
||||||
import dev.engine_room.flywheel.api.backend.BackendManager;
|
import dev.engine_room.flywheel.api.backend.BackendManager;
|
||||||
|
import dev.engine_room.flywheel.backend.BackendDebugFlags;
|
||||||
import dev.engine_room.flywheel.backend.compile.LightSmoothness;
|
import dev.engine_room.flywheel.backend.compile.LightSmoothness;
|
||||||
import dev.engine_room.flywheel.backend.compile.PipelineCompiler;
|
import dev.engine_room.flywheel.backend.compile.PipelineCompiler;
|
||||||
import dev.engine_room.flywheel.backend.engine.LightStorage;
|
|
||||||
import dev.engine_room.flywheel.backend.engine.uniform.DebugMode;
|
import dev.engine_room.flywheel.backend.engine.uniform.DebugMode;
|
||||||
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
|
import dev.engine_room.flywheel.backend.engine.uniform.FrameUniforms;
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
|
@ -172,14 +172,27 @@ public final class FlwCommands {
|
||||||
debug.then(Commands.literal("lightSections")
|
debug.then(Commands.literal("lightSections")
|
||||||
.then(Commands.literal("on")
|
.then(Commands.literal("on")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
LightStorage.DEBUG = true;
|
BackendDebugFlags.LIGHT_STORAGE_VIEW = true;
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
}))
|
}))
|
||||||
.then(Commands.literal("off")
|
.then(Commands.literal("off")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
LightStorage.DEBUG = false;
|
BackendDebugFlags.LIGHT_STORAGE_VIEW = false;
|
||||||
return Command.SINGLE_SUCCESS;
|
return Command.SINGLE_SUCCESS;
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
debug.then(Commands.literal("pauseUpdates")
|
||||||
|
.then(Commands.literal("on")
|
||||||
|
.executes(context -> {
|
||||||
|
ImplDebugFlags.PAUSE_UPDATES = true;
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
|
}))
|
||||||
|
.then(Commands.literal("off")
|
||||||
|
.executes(context -> {
|
||||||
|
ImplDebugFlags.PAUSE_UPDATES = false;
|
||||||
|
return Command.SINGLE_SUCCESS;
|
||||||
|
})));
|
||||||
|
|
||||||
return debug;
|
return debug;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue