Skip to content

Commit c945ad2

Browse files
committed
Experimental caching noise biome source
1 parent e411f11 commit c945ad2

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package org.embeddedt.modernfix.common.mixin.perf.worldgen_allocation;
2+
3+
import com.llamalad7.mixinextras.sugar.Local;
4+
import net.minecraft.core.BlockPos;
5+
import net.minecraft.core.Holder;
6+
import net.minecraft.core.QuartPos;
7+
import net.minecraft.world.level.biome.Biome;
8+
import net.minecraft.world.level.biome.BiomeManager;
9+
import net.minecraft.world.level.chunk.ChunkAccess;
10+
import net.minecraft.world.level.levelgen.SurfaceSystem;
11+
import org.embeddedt.modernfix.world.gen.CachingNoiseBiomeSource;
12+
import org.spongepowered.asm.mixin.Mixin;
13+
import org.spongepowered.asm.mixin.injection.At;
14+
import org.spongepowered.asm.mixin.injection.ModifyArg;
15+
16+
import java.util.function.Function;
17+
18+
@Mixin(SurfaceSystem.class)
19+
public class SurfaceSystemMixin {
20+
@ModifyArg(method = "buildSurface", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/levelgen/SurfaceRules$Context;<init>(Lnet/minecraft/world/level/levelgen/SurfaceSystem;Lnet/minecraft/world/level/levelgen/RandomState;Lnet/minecraft/world/level/chunk/ChunkAccess;Lnet/minecraft/world/level/levelgen/NoiseChunk;Ljava/util/function/Function;Lnet/minecraft/core/Registry;Lnet/minecraft/world/level/levelgen/WorldGenerationContext;)V"), index = 4)
21+
private Function<BlockPos, Holder<Biome>> createBiomeManagerBoundToChunk(Function<BlockPos, Holder<Biome>> biomeGetter, @Local(ordinal = 0, argsOnly = true) BiomeManager manager, @Local(ordinal = 0, argsOnly = true) ChunkAccess chunk) {
22+
var chunkPos = chunk.getPos();
23+
return manager.withDifferentSource(new CachingNoiseBiomeSource(
24+
manager::getNoiseBiomeAtQuart,
25+
QuartPos.fromSection(chunkPos.x),
26+
QuartPos.fromSection(chunkPos.z),
27+
chunk.getHeight(),
28+
Math.abs(chunk.getMinBuildHeight())
29+
))::getBiome;
30+
}
31+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.embeddedt.modernfix.world.gen;
2+
3+
import net.minecraft.core.Holder;
4+
import net.minecraft.core.QuartPos;
5+
import net.minecraft.world.level.biome.Biome;
6+
import net.minecraft.world.level.biome.BiomeManager;
7+
8+
public class CachingNoiseBiomeSource implements BiomeManager.NoiseBiomeSource {
9+
private static final boolean DEBUG_OOB = false;
10+
private static final int HORIZONTAL_CELLS_PER_CHUNK = 8;
11+
private static final int CELL_SHIFT = 2;
12+
private final BiomeManager.NoiseBiomeSource biomeSource;
13+
private final Holder<Biome>[] biomesInCells;
14+
private final int numVerticalCells;
15+
private final int verticalShift;
16+
private final int chunkOriginX, chunkOriginZ;
17+
18+
public CachingNoiseBiomeSource(BiomeManager.NoiseBiomeSource backingSource, int chunkOriginX, int chunkOriginZ, int worldHeight, int numBlocksBelowYZero) {
19+
this.biomeSource = backingSource;
20+
this.numVerticalCells = worldHeight / QuartPos.SIZE + 2;
21+
this.chunkOriginX = chunkOriginX;
22+
this.chunkOriginZ = chunkOriginZ;
23+
this.verticalShift = numBlocksBelowYZero / QuartPos.SIZE;
24+
this.biomesInCells = new Holder[numVerticalCells * HORIZONTAL_CELLS_PER_CHUNK * HORIZONTAL_CELLS_PER_CHUNK];
25+
}
26+
27+
private static int getLocalIndex(int relX, int relY, int relZ) {
28+
return (relY * HORIZONTAL_CELLS_PER_CHUNK * HORIZONTAL_CELLS_PER_CHUNK) + (relZ * HORIZONTAL_CELLS_PER_CHUNK) + relX;
29+
}
30+
31+
@Override
32+
public Holder<Biome> getNoiseBiome(int x, int y, int z) {
33+
int relX = x + CELL_SHIFT - this.chunkOriginX;
34+
int relZ = z + CELL_SHIFT - this.chunkOriginZ;
35+
int relY = y + this.verticalShift + 1;
36+
if (((relX | relZ) & ~(HORIZONTAL_CELLS_PER_CHUNK - 1)) != 0 || relY < 0 || relY >= this.numVerticalCells) {
37+
return this.biomeSource.getNoiseBiome(x, y, z);
38+
}
39+
int i = getLocalIndex(relX, relY, relZ);
40+
if (DEBUG_OOB) {
41+
if (i < 0 || i >= this.biomesInCells.length) {
42+
throw new ArrayIndexOutOfBoundsException("Error: Requested noise biome cell is out of range: (%d, %d, %d)".formatted(relX, relY, relZ));
43+
}
44+
}
45+
var biomes = this.biomesInCells;
46+
var result = biomes[i];
47+
if (result == null) {
48+
result = this.biomeSource.getNoiseBiome(x, y, z);
49+
biomes[i] = result;
50+
}
51+
return result;
52+
}
53+
}

0 commit comments

Comments
 (0)