mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-06-18 14:50:56 +00:00
implement SamplerCache for drastically increased structure perf
This commit is contained in:
@@ -21,7 +21,7 @@ import com.dfsek.terra.api.structures.script.builders.UnaryNumberFunctionBuilder
|
|||||||
import com.dfsek.terra.api.structures.structure.Rotation;
|
import com.dfsek.terra.api.structures.structure.Rotation;
|
||||||
import com.dfsek.terra.api.structures.structure.buffer.Buffer;
|
import com.dfsek.terra.api.structures.structure.buffer.Buffer;
|
||||||
import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer;
|
import com.dfsek.terra.api.structures.structure.buffer.StructureBuffer;
|
||||||
import com.dfsek.terra.api.structures.world.CheckCache;
|
import com.dfsek.terra.generation.math.SamplerCache;
|
||||||
import com.dfsek.terra.registry.LootRegistry;
|
import com.dfsek.terra.registry.LootRegistry;
|
||||||
import com.dfsek.terra.registry.ScriptRegistry;
|
import com.dfsek.terra.registry.ScriptRegistry;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
@@ -38,7 +38,7 @@ public class StructureScript {
|
|||||||
private final String id;
|
private final String id;
|
||||||
private final LinkedHashMap<Location, StructureBuffer> cache;
|
private final LinkedHashMap<Location, StructureBuffer> cache;
|
||||||
|
|
||||||
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, CheckCache cache) throws ParseException {
|
public StructureScript(InputStream inputStream, TerraPlugin main, ScriptRegistry registry, LootRegistry lootRegistry, SamplerCache cache) throws ParseException {
|
||||||
Parser parser;
|
Parser parser;
|
||||||
try {
|
try {
|
||||||
parser = new Parser(IOUtils.toString(inputStream));
|
parser = new Parser(IOUtils.toString(inputStream));
|
||||||
|
|||||||
+3
-3
@@ -6,15 +6,15 @@ import com.dfsek.terra.api.structures.parser.lang.Returnable;
|
|||||||
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder;
|
||||||
import com.dfsek.terra.api.structures.script.functions.CheckFunction;
|
import com.dfsek.terra.api.structures.script.functions.CheckFunction;
|
||||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||||
import com.dfsek.terra.api.structures.world.CheckCache;
|
import com.dfsek.terra.generation.math.SamplerCache;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CheckFunctionBuilder implements FunctionBuilder<CheckFunction> {
|
public class CheckFunctionBuilder implements FunctionBuilder<CheckFunction> {
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
private final CheckCache cache;
|
private final SamplerCache cache;
|
||||||
|
|
||||||
public CheckFunctionBuilder(TerraPlugin main, CheckCache cache) {
|
public CheckFunctionBuilder(TerraPlugin main, SamplerCache cache) {
|
||||||
this.main = main;
|
this.main = main;
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -12,20 +12,20 @@ import com.dfsek.terra.api.structures.parser.lang.functions.Function;
|
|||||||
import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
|
import com.dfsek.terra.api.structures.script.TerraImplementationArguments;
|
||||||
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
import com.dfsek.terra.api.structures.structure.RotationUtil;
|
||||||
import com.dfsek.terra.api.structures.tokenizer.Position;
|
import com.dfsek.terra.api.structures.tokenizer.Position;
|
||||||
import com.dfsek.terra.api.structures.world.CheckCache;
|
|
||||||
import com.dfsek.terra.api.world.generation.GenerationPhase;
|
import com.dfsek.terra.api.world.generation.GenerationPhase;
|
||||||
import com.dfsek.terra.biome.UserDefinedBiome;
|
import com.dfsek.terra.biome.UserDefinedBiome;
|
||||||
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
|
import com.dfsek.terra.biome.grid.master.TerraBiomeGrid;
|
||||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||||
|
import com.dfsek.terra.generation.math.SamplerCache;
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
public class CheckFunction implements Function<String> {
|
public class CheckFunction implements Function<String> {
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
private final Returnable<Number> x, y, z;
|
private final Returnable<Number> x, y, z;
|
||||||
private final Position position;
|
private final Position position;
|
||||||
private final CheckCache cache;
|
private final SamplerCache cache;
|
||||||
|
|
||||||
public CheckFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, CheckCache cache, Position position) {
|
public CheckFunction(TerraPlugin main, Returnable<Number> x, Returnable<Number> y, Returnable<Number> z, SamplerCache cache, Position position) {
|
||||||
this.main = main;
|
this.main = main;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.y = y;
|
this.y = y;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import com.dfsek.terra.api.LoaderRegistrar;
|
|||||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||||
import com.dfsek.terra.api.structures.loot.LootTable;
|
import com.dfsek.terra.api.structures.loot.LootTable;
|
||||||
import com.dfsek.terra.api.structures.script.StructureScript;
|
import com.dfsek.terra.api.structures.script.StructureScript;
|
||||||
import com.dfsek.terra.api.structures.world.CheckCache;
|
|
||||||
import com.dfsek.terra.api.world.biome.Biome;
|
import com.dfsek.terra.api.world.biome.Biome;
|
||||||
import com.dfsek.terra.api.world.flora.Flora;
|
import com.dfsek.terra.api.world.flora.Flora;
|
||||||
import com.dfsek.terra.api.world.palette.Palette;
|
import com.dfsek.terra.api.world.palette.Palette;
|
||||||
@@ -43,6 +42,7 @@ import com.dfsek.terra.config.templates.StructureTemplate;
|
|||||||
import com.dfsek.terra.config.templates.TreeTemplate;
|
import com.dfsek.terra.config.templates.TreeTemplate;
|
||||||
import com.dfsek.terra.generation.items.TerraStructure;
|
import com.dfsek.terra.generation.items.TerraStructure;
|
||||||
import com.dfsek.terra.generation.items.ores.Ore;
|
import com.dfsek.terra.generation.items.ores.Ore;
|
||||||
|
import com.dfsek.terra.generation.math.SamplerCache;
|
||||||
import com.dfsek.terra.registry.BiomeGridRegistry;
|
import com.dfsek.terra.registry.BiomeGridRegistry;
|
||||||
import com.dfsek.terra.registry.BiomeRegistry;
|
import com.dfsek.terra.registry.BiomeRegistry;
|
||||||
import com.dfsek.terra.registry.CarverRegistry;
|
import com.dfsek.terra.registry.CarverRegistry;
|
||||||
@@ -95,12 +95,12 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
private final ConfigLoader selfLoader = new ConfigLoader();
|
private final ConfigLoader selfLoader = new ConfigLoader();
|
||||||
private final Scope varScope = new Scope();
|
private final Scope varScope = new Scope();
|
||||||
|
|
||||||
private final CheckCache checkCache;
|
private final SamplerCache samplerCache;
|
||||||
|
|
||||||
|
|
||||||
public ConfigPack(File folder, TerraPlugin main) throws ConfigException {
|
public ConfigPack(File folder, TerraPlugin main) throws ConfigException {
|
||||||
long l = System.nanoTime();
|
long l = System.nanoTime();
|
||||||
this.checkCache = new CheckCache(main);
|
this.samplerCache = new SamplerCache(main);
|
||||||
floraRegistry = new FloraRegistry(main);
|
floraRegistry = new FloraRegistry(main);
|
||||||
paletteRegistry = new PaletteRegistry(main);
|
paletteRegistry = new PaletteRegistry(main);
|
||||||
treeRegistry = new TreeRegistry(main);
|
treeRegistry = new TreeRegistry(main);
|
||||||
@@ -122,7 +122,7 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
|
|
||||||
public ConfigPack(ZipFile file, TerraPlugin main) throws ConfigException {
|
public ConfigPack(ZipFile file, TerraPlugin main) throws ConfigException {
|
||||||
long l = System.nanoTime();
|
long l = System.nanoTime();
|
||||||
this.checkCache = new CheckCache(main);
|
this.samplerCache = new SamplerCache(main);
|
||||||
floraRegistry = new FloraRegistry(main);
|
floraRegistry = new FloraRegistry(main);
|
||||||
paletteRegistry = new PaletteRegistry(main);
|
paletteRegistry = new PaletteRegistry(main);
|
||||||
treeRegistry = new TreeRegistry(main);
|
treeRegistry = new TreeRegistry(main);
|
||||||
@@ -157,7 +157,7 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
loader.open("structures/data", ".tesf").thenEntries(entries -> {
|
loader.open("structures/data", ".tesf").thenEntries(entries -> {
|
||||||
for(Map.Entry<String, InputStream> entry : entries) {
|
for(Map.Entry<String, InputStream> entry : entries) {
|
||||||
try {
|
try {
|
||||||
StructureScript structureScript = new StructureScript(entry.getValue(), main, scriptRegistry, lootRegistry, checkCache);
|
StructureScript structureScript = new StructureScript(entry.getValue(), main, scriptRegistry, lootRegistry, samplerCache);
|
||||||
scriptRegistry.add(structureScript.getId(), structureScript);
|
scriptRegistry.add(structureScript.getId(), structureScript);
|
||||||
} catch(com.dfsek.terra.api.structures.parser.exceptions.ParseException e) {
|
} catch(com.dfsek.terra.api.structures.parser.exceptions.ParseException e) {
|
||||||
throw new LoadException("Unable to load script \"" + entry.getKey() + "\"", e);
|
throw new LoadException("Unable to load script \"" + entry.getKey() + "\"", e);
|
||||||
@@ -278,7 +278,7 @@ public class ConfigPack implements LoaderRegistrar {
|
|||||||
return biomeRegistry;
|
return biomeRegistry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CheckCache getCheckCache() {
|
public SamplerCache getSamplerCache() {
|
||||||
return checkCache;
|
return samplerCache;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.dfsek.terra.biome.palette.SinglePalette;
|
|||||||
import com.dfsek.terra.config.base.ConfigPack;
|
import com.dfsek.terra.config.base.ConfigPack;
|
||||||
import com.dfsek.terra.config.templates.BiomeTemplate;
|
import com.dfsek.terra.config.templates.BiomeTemplate;
|
||||||
import com.dfsek.terra.generation.math.Sampler;
|
import com.dfsek.terra.generation.math.Sampler;
|
||||||
|
import com.dfsek.terra.generation.math.SamplerCache;
|
||||||
import com.dfsek.terra.util.PaletteUtil;
|
import com.dfsek.terra.util.PaletteUtil;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@@ -37,12 +38,15 @@ public class MasterChunkGenerator implements TerraChunkGenerator {
|
|||||||
private final MaterialData water;
|
private final MaterialData water;
|
||||||
private final SinglePalette<BlockData> blank;
|
private final SinglePalette<BlockData> blank;
|
||||||
|
|
||||||
|
private final SamplerCache cache;
|
||||||
|
|
||||||
public MasterChunkGenerator(ConfigPack c, TerraPlugin main) {
|
|
||||||
|
public MasterChunkGenerator(ConfigPack c, TerraPlugin main, SamplerCache cache) {
|
||||||
this.configPack = c;
|
this.configPack = c;
|
||||||
this.main = main;
|
this.main = main;
|
||||||
water = main.getWorldHandle().createMaterialData("minecraft:water");
|
water = main.getWorldHandle().createMaterialData("minecraft:water");
|
||||||
blank = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:air"));
|
blank = new SinglePalette<>(main.getWorldHandle().createBlockData("minecraft:air"));
|
||||||
|
this.cache = cache;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -91,7 +95,7 @@ public class MasterChunkGenerator implements TerraChunkGenerator {
|
|||||||
int xOrig = (chunkX << 4);
|
int xOrig = (chunkX << 4);
|
||||||
int zOrig = (chunkZ << 4);
|
int zOrig = (chunkZ << 4);
|
||||||
|
|
||||||
Sampler sampler = new Sampler(chunkX, chunkZ, tw.getGrid(), world, configPack.getTemplate().getElevationBlend(), configPack.getTemplate().getBaseBlend());
|
Sampler sampler = cache.getChunk(world, chunkX, chunkZ);
|
||||||
|
|
||||||
for(byte x = 0; x < 16; x++) {
|
for(byte x = 0; x < 16; x++) {
|
||||||
for(byte z = 0; z < 16; z++) {
|
for(byte z = 0; z < 16; z++) {
|
||||||
|
|||||||
+17
-5
@@ -1,20 +1,19 @@
|
|||||||
package com.dfsek.terra.api.structures.world;
|
package com.dfsek.terra.generation.math;
|
||||||
|
|
||||||
import com.dfsek.terra.TerraWorld;
|
import com.dfsek.terra.TerraWorld;
|
||||||
import com.dfsek.terra.api.platform.TerraPlugin;
|
import com.dfsek.terra.api.platform.TerraPlugin;
|
||||||
import com.dfsek.terra.api.platform.world.World;
|
import com.dfsek.terra.api.platform.world.World;
|
||||||
import com.dfsek.terra.generation.math.Sampler;
|
|
||||||
import net.jafama.FastMath;
|
import net.jafama.FastMath;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class CheckCache {
|
public class SamplerCache {
|
||||||
private final Map<Long, Container> cache;
|
private final Map<Long, Container> cache;
|
||||||
private final TerraPlugin main;
|
private final TerraPlugin main;
|
||||||
|
|
||||||
public CheckCache(TerraPlugin main) {
|
public SamplerCache(TerraPlugin main) {
|
||||||
cache = new HashMap<>();
|
cache = new HashMap<>();
|
||||||
this.main = main;
|
this.main = main;
|
||||||
}
|
}
|
||||||
@@ -28,6 +27,15 @@ public class CheckCache {
|
|||||||
})).get(x, z);
|
})).get(x, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Sampler getChunk(World world, int chunkX, int chunkZ) {
|
||||||
|
return cache.computeIfAbsent(world.getSeed(), seed -> new Container(world, new LinkedHashMap<Long, Sampler>() {
|
||||||
|
@Override
|
||||||
|
protected boolean removeEldestEntry(Map.Entry<Long, Sampler> eldest) {
|
||||||
|
return size() > main.getTerraConfig().getCheckCache();
|
||||||
|
}
|
||||||
|
})).getChunk(chunkX, chunkZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private class Container {
|
private class Container {
|
||||||
private final World world;
|
private final World world;
|
||||||
@@ -41,9 +49,13 @@ public class CheckCache {
|
|||||||
public Sampler get(int x, int z) {
|
public Sampler get(int x, int z) {
|
||||||
int cx = FastMath.floorDiv(x, 16);
|
int cx = FastMath.floorDiv(x, 16);
|
||||||
int cz = FastMath.floorDiv(z, 16);
|
int cz = FastMath.floorDiv(z, 16);
|
||||||
|
return getChunk(cx, cz);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Sampler getChunk(int cx, int cz) {
|
||||||
long key = (((long) cx) << 32) | (cz & 0xffffffffL);
|
long key = (((long) cx) << 32) | (cz & 0xffffffffL);
|
||||||
TerraWorld tw = main.getWorld(world);
|
TerraWorld tw = main.getWorld(world);
|
||||||
return cache.computeIfAbsent(key, k -> new Sampler(cx, cz, tw.getGrid(), world, 4, 8));
|
return cache.computeIfAbsent(key, k -> new Sampler(cx, cz, tw.getGrid(), world, tw.getConfig().getTemplate().getBaseBlend(), tw.getConfig().getTemplate().getElevationBlend()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -145,8 +145,9 @@ public class TerraBukkitPlugin extends JavaPlugin implements TerraPlugin {
|
|||||||
public @Nullable ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, @Nullable String id) {
|
public @Nullable ChunkGenerator getDefaultWorldGenerator(@NotNull String worldName, @Nullable String id) {
|
||||||
return new BukkitChunkGeneratorWrapper(generatorMap.computeIfAbsent(worldName, name -> {
|
return new BukkitChunkGeneratorWrapper(generatorMap.computeIfAbsent(worldName, name -> {
|
||||||
if(!registry.contains(id)) throw new IllegalArgumentException("No such config pack \"" + id + "\"");
|
if(!registry.contains(id)) throw new IllegalArgumentException("No such config pack \"" + id + "\"");
|
||||||
worlds.put(worldName, registry.get(id));
|
ConfigPack pack = registry.get(id);
|
||||||
return new MasterChunkGenerator(registry.get(id), this);
|
worlds.put(worldName, pack);
|
||||||
|
return new MasterChunkGenerator(registry.get(id), this, pack.getSamplerCache());
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -33,7 +33,7 @@ public class SpawnCommand extends WorldCommand implements DebugCommand {
|
|||||||
int z = p.getBlockZ();
|
int z = p.getBlockZ();
|
||||||
Position dummy = new Position(0, 0);
|
Position dummy = new Position(0, 0);
|
||||||
com.dfsek.terra.api.platform.world.World w = BukkitAdapter.adapt(world);
|
com.dfsek.terra.api.platform.world.World w = BukkitAdapter.adapt(world);
|
||||||
String check = new CheckFunction(getMain(), new NumericConstant(0, dummy), new NumericConstant(0, dummy), new NumericConstant(0, dummy), getMain().getWorld(w).getConfig().getCheckCache(), dummy).apply(new TerraImplementationArguments(new StructureBuffer(
|
String check = new CheckFunction(getMain(), new NumericConstant(0, dummy), new NumericConstant(0, dummy), new NumericConstant(0, dummy), getMain().getWorld(w).getConfig().getSamplerCache(), dummy).apply(new TerraImplementationArguments(new StructureBuffer(
|
||||||
new com.dfsek.terra.api.math.vector.Location(w, x, y, z)
|
new com.dfsek.terra.api.math.vector.Location(w, x, y, z)
|
||||||
), Rotation.NONE, new FastRandom(), 0));
|
), Rotation.NONE, new FastRandom(), 0));
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,6 @@ dump-default: true
|
|||||||
biome-search-resolution: 4
|
biome-search-resolution: 4
|
||||||
cache:
|
cache:
|
||||||
carver: 512
|
carver: 512
|
||||||
structure: 128
|
structure: 1024
|
||||||
master-disable:
|
master-disable:
|
||||||
caves: false
|
caves: false
|
||||||
+1
-1
@@ -76,7 +76,7 @@ public class FabricChunkGeneratorWrapper extends ChunkGenerator implements Gener
|
|||||||
super(biomeSource, new StructuresConfig(false));
|
super(biomeSource, new StructuresConfig(false));
|
||||||
this.pack = configPack;
|
this.pack = configPack;
|
||||||
|
|
||||||
this.delegate = new MasterChunkGenerator(configPack, TerraFabricPlugin.getInstance());
|
this.delegate = new MasterChunkGenerator(configPack, TerraFabricPlugin.getInstance(), pack.getSamplerCache());
|
||||||
delegate.getMain().getLogger().info("Loading world...");
|
delegate.getMain().getLogger().info("Loading world...");
|
||||||
this.biomeSource = biomeSource;
|
this.biomeSource = biomeSource;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user