tweeked how chunkbound renderer detects changes, auto ingest section when section status changes while surounded by loaded chunks

This commit is contained in:
mcrcortex
2025-08-25 23:42:44 +10:00
parent 120f1e2018
commit 3533d2356c
5 changed files with 72 additions and 2 deletions

View File

@@ -436,4 +436,8 @@ public class VoxyRenderSystem {
}
return geometryCapacity;
}
public WorldEngine getEngine() {
return this.worldIn;
}
}

View File

@@ -0,0 +1,12 @@
package me.cortex.voxy.client.mixin.sodium;
import it.unimi.dsi.fastutil.longs.Long2IntOpenHashMap;
import net.caffeinemc.mods.sodium.client.render.chunk.map.ChunkTracker;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
@Mixin(value = ChunkTracker.class, remap = false)
public interface AccessorChunkTracker {
@Accessor
Long2IntOpenHashMap getChunkStatus();
}

View File

@@ -6,13 +6,17 @@ import me.cortex.voxy.client.core.IGetVoxyRenderSystem;
import me.cortex.voxy.client.core.VoxyRenderSystem;
import me.cortex.voxy.common.world.service.VoxelIngestService;
import me.cortex.voxy.commonImpl.VoxyCommon;
import me.cortex.voxy.commonImpl.WorldIdentifier;
import net.caffeinemc.mods.sodium.client.gl.device.CommandList;
import net.caffeinemc.mods.sodium.client.render.chunk.RenderSection;
import net.caffeinemc.mods.sodium.client.render.chunk.RenderSectionManager;
import net.caffeinemc.mods.sodium.client.render.chunk.data.BuiltSectionInfo;
import net.caffeinemc.mods.sodium.client.render.chunk.map.ChunkTrackerHolder;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.ChunkSectionPos;
import net.minecraft.world.LightType;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@@ -37,6 +41,7 @@ public class MixinRenderSectionManager {
system.chunkBoundRenderer.reset();
}
}
this.bottomSectionY = this.level.getBottomY()>>4;
}
@Inject(method = "onChunkRemoved", at = @At("HEAD"))
@@ -75,16 +80,21 @@ public class MixinRenderSectionManager {
}
}*/
@Unique private long cachedChunkPos = -1;
@Unique private int cachedChunkStatus;
@Unique private int bottomSectionY;
@Redirect(method = "updateSectionInfo", at = @At(value = "INVOKE", target = "Lnet/caffeinemc/mods/sodium/client/render/chunk/RenderSection;setInfo(Lnet/caffeinemc/mods/sodium/client/render/chunk/data/BuiltSectionInfo;)Z"))
private boolean voxy$updateOnUpload(RenderSection instance, BuiltSectionInfo info) {
boolean wasBuilt = instance.isBuilt();
boolean wasBuilt = instance.getFlags()!=0;
int flags = instance.getFlags();
if (!instance.setInfo(info)) {
return false;
}
if (wasBuilt == instance.isBuilt()) {//Only want to do stuff on change
if (wasBuilt == (instance.getFlags()!=0)) {//Only want to do stuff on change
return true;
}
flags |= instance.getFlags();
if (flags == 0)//Only process things with stuff
return true;
@@ -94,6 +104,30 @@ public class MixinRenderSectionManager {
return true;
}
int x = instance.getChunkX(), y = instance.getChunkY(), z = instance.getChunkZ();
if (wasBuilt) {
var tracker = ((AccessorChunkTracker)ChunkTrackerHolder.get(this.level)).getChunkStatus();
//in theory the cache value could be wrong but is so soso unlikely and at worst means we either duplicate ingest a chunk
// which... could be bad ;-; or we dont ingest atall which is ok!
long key = ChunkPos.toLong(x, z);
if (key != this.cachedChunkPos) {
this.cachedChunkPos = key;
this.cachedChunkStatus = tracker.getOrDefault(key, 0);
}
if (this.cachedChunkStatus == 3) {//If this chunk still has surrounding chunks
var section = this.level.getChunk(x,z).getSection(y-this.bottomSectionY);
var lp = this.level.getLightingProvider();
var csp = ChunkSectionPos.from(x,y,z);
var blp = lp.get(LightType.BLOCK).getLightSection(csp);
var slp = lp.get(LightType.SKY).getLightSection(csp);
//Note: we dont do this check and just blindly ingest, it shouldbe ok :tm:
//if (blp != null || slp != null)
VoxelIngestService.rawIngest(system.getEngine(), section, x,y,z, blp==null?null:blp.copy(), slp==null?null:slp.copy());
}
}
//Do some very cheeky stuff for MiB
if (VoxyCommon.IS_MINE_IN_ABYSS) {
int sector = (x+512)>>10;
@@ -102,6 +136,8 @@ public class MixinRenderSectionManager {
}
long pos = ChunkSectionPos.asLong(x,y,z);
if (wasBuilt) {//Remove
//TODO: on chunk remove do ingest if is surrounded by built chunks (or when the tracker says is ok)
system.chunkBoundRenderer.removeSection(pos);
} else {//Add
system.chunkBoundRenderer.addSection(pos);

View File

@@ -187,4 +187,21 @@ public class VoxelIngestService {
public static boolean tryAutoIngestChunk(WorldChunk chunk) {
return tryIngestChunk(WorldIdentifier.of(chunk.getWorld()), chunk);
}
private boolean rawIngest0(WorldEngine engine, ChunkSection section, int x, int y, int z, ChunkNibbleArray bl, ChunkNibbleArray sl) {
this.ingestQueue.add(new IngestSection(x, y, z, engine, section, bl, sl));
try {
this.threads.execute();
return true;
} catch (Exception e) {
Logger.error("Executing had an error: assume shutting down, aborting",e);
return false;
}
}
public static boolean rawIngest(WorldEngine engine, ChunkSection section, int x, int y, int z, ChunkNibbleArray bl, ChunkNibbleArray sl) {
if (!shouldIngestSection(section, x, y, z)) return false;
if (engine.instanceIn == null) return false;
return engine.instanceIn.getIngestService().rawIngest0(engine, section, x, y, z, bl, sl);
}
}

View File

@@ -23,6 +23,7 @@
"minecraft.MixinWindow",
"minecraft.MixinWorldRenderer",
"nvidium.MixinRenderPipeline",
"sodium.AccessorChunkTracker",
"sodium.MixinDefaultChunkRenderer",
"sodium.MixinRenderSectionManager",
"sodium.MixinSodiumOptionsGUI"