mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-14 08:16:13 +01:00
Missing section misdirection
- Avoid adding all sections every frame - Remove sections when they are no longer needed - Rebuild the lut when sections are removed - Properly detect missing sections by writing 1-based indices to the lut
This commit is contained in:
parent
cf2c11a37c
commit
2a0694ccaf
5 changed files with 50 additions and 16 deletions
|
@ -46,7 +46,8 @@ public class EngineImpl implements Engine {
|
|||
|
||||
@Override
|
||||
public Plan<RenderContext> createFramePlan() {
|
||||
return lightStorage.createFramePlan().then(SyncedPlan.of(this::flush));
|
||||
return lightStorage.createFramePlan()
|
||||
.then(SyncedPlan.of(this::flush));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -80,7 +80,8 @@ public class LightLut {
|
|||
zLookup.ensureCapacity(zIndex + 3);
|
||||
zLookup.size(zIndex + 3);
|
||||
}
|
||||
zLookup.set(zIndex + 2, sectionIndicesMaps.get(position));
|
||||
// Add 1 to the actual index so that 0 indicates a missing section.
|
||||
zLookup.set(zIndex + 2, sectionIndicesMaps.get(position) + 1);
|
||||
}
|
||||
return indices;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import dev.engine_room.flywheel.lib.task.SimplePlan;
|
|||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.longs.Long2IntMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
|
||||
import it.unimi.dsi.fastutil.longs.LongSet;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.world.level.LevelAccessor;
|
||||
|
@ -47,7 +48,7 @@ public class LightStorage {
|
|||
}
|
||||
|
||||
private final BitSet changed = new BitSet();
|
||||
private boolean newSections = false;
|
||||
private boolean needsLutRebuild = false;
|
||||
|
||||
public LightStorage(LevelAccessor level, EnvironmentStorage environmentStorage) {
|
||||
this.level = level;
|
||||
|
@ -58,11 +59,34 @@ public class LightStorage {
|
|||
|
||||
public Plan<RenderContext> createFramePlan() {
|
||||
return SimplePlan.of(() -> {
|
||||
var longs = environmentStorage.allLightSections();
|
||||
longs.forEach(this::addSection);
|
||||
var allLightSections = environmentStorage.allLightSections();
|
||||
|
||||
removeUnusedSections(allLightSections);
|
||||
|
||||
// Only add the new sections.
|
||||
allLightSections.removeAll(section2ArenaIndex.keySet());
|
||||
|
||||
for (var section : allLightSections) {
|
||||
addSection(section);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void removeUnusedSections(LongSet allLightSections) {
|
||||
var entries = section2ArenaIndex.long2IntEntrySet();
|
||||
var it = entries.iterator();
|
||||
while (it.hasNext()) {
|
||||
var entry = it.next();
|
||||
var section = entry.getLongKey();
|
||||
|
||||
if (!allLightSections.contains(section)) {
|
||||
arena.free(entry.getIntValue());
|
||||
needsLutRebuild = true;
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int capacity() {
|
||||
return arena.capacity();
|
||||
}
|
||||
|
@ -179,15 +203,11 @@ public class LightStorage {
|
|||
if (out == INVALID_SECTION) {
|
||||
out = arena.alloc();
|
||||
section2ArenaIndex.put(section, out);
|
||||
newSections = true;
|
||||
needsLutRebuild = true;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
public void removeSection(long section) {
|
||||
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
arena.delete();
|
||||
}
|
||||
|
@ -196,8 +216,10 @@ public class LightStorage {
|
|||
return !changed.isEmpty();
|
||||
}
|
||||
|
||||
public boolean hasNewSections() {
|
||||
return newSections;
|
||||
public boolean checkNeedsLutRebuildAndClear() {
|
||||
var out = needsLutRebuild;
|
||||
needsLutRebuild = false;
|
||||
return out;
|
||||
}
|
||||
|
||||
public void uploadChangedSections(StagingBuffer staging, int dstVbo) {
|
||||
|
@ -208,6 +230,7 @@ public class LightStorage {
|
|||
}
|
||||
|
||||
public IntArrayList createLut() {
|
||||
// TODO: incremental lut updates
|
||||
return LightLut.buildLut(section2ArenaIndex);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ public class LightBuffers {
|
|||
lightArena.ensureCapacity(capacity);
|
||||
light.uploadChangedSections(staging, lightArena.handle());
|
||||
|
||||
if (light.hasNewSections()) {
|
||||
if (light.checkNeedsLutRebuildAndClear()) {
|
||||
var lut = light.createLut();
|
||||
|
||||
this.lut.ensureCapacity(lut.size());
|
||||
|
|
|
@ -42,15 +42,24 @@ bool _flw_nextLut(uint base, int coord, out uint next) {
|
|||
|
||||
bool _flw_chunkCoordToSectionIndex(ivec3 sectionPos, out uint index) {
|
||||
uint y;
|
||||
if (_flw_nextLut(0, sectionPos.x, y)) {
|
||||
if (_flw_nextLut(0, sectionPos.x, y) || y == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint z;
|
||||
if (_flw_nextLut(y, sectionPos.y, z)) {
|
||||
if (_flw_nextLut(y, sectionPos.y, z) || z == 0) {
|
||||
return true;
|
||||
}
|
||||
return _flw_nextLut(z, sectionPos.z, index);
|
||||
|
||||
uint sectionIndex;
|
||||
if (_flw_nextLut(z, sectionPos.z, index) || index == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// The index is written as 1-based so we can properly detect missing sections.
|
||||
index = sectionIndex - 1;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
vec2 _flw_lightAt(uint sectionOffset, uvec3 blockInSectionPos) {
|
||||
|
|
Loading…
Reference in a new issue