mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 14:30:14 +00:00
Cheaper cave biome resolution
- carving root entries cached per world Y in arrays instead of a boxed-key map - semantic cave capture skips re-adding the key it added last
This commit is contained in:
1 parent
2fef055e5c
commit
c00dfbddce
3 files changed
+48
-15
No files matched your search
+35
-9
@@ -14,7 +14,7 @@ import art.arcane.volmlib.util.noise.CNG;
|
|||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.Arrays;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -81,8 +81,9 @@ public final class IrisDimensionCarvingResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static IrisDimensionCarvingEntry resolveBoundRootEntry(Engine engine, int worldY, IrisData data, State resolvedState) {
|
private static IrisDimensionCarvingEntry resolveBoundRootEntry(Engine engine, int worldY, IrisData data, State resolvedState) {
|
||||||
if (resolvedState.rootEntriesByWorldY.containsKey(worldY)) {
|
int slot = resolvedState.rootSlot(worldY);
|
||||||
return resolvedState.rootEntriesByWorldY.get(worldY);
|
if (slot >= 0) {
|
||||||
|
return resolvedState.roots[slot];
|
||||||
}
|
}
|
||||||
|
|
||||||
return selectBoundRootEntry(engine.getDimension(), worldY, data, resolvedState);
|
return selectBoundRootEntry(engine.getDimension(), worldY, data, resolvedState);
|
||||||
@@ -91,7 +92,7 @@ public final class IrisDimensionCarvingResolver {
|
|||||||
private static IrisDimensionCarvingEntry selectBoundRootEntry(IrisDimension dimension, int worldY, IrisData data, State resolvedState) {
|
private static IrisDimensionCarvingEntry selectBoundRootEntry(IrisDimension dimension, int worldY, IrisData data, State resolvedState) {
|
||||||
List<IrisDimensionCarvingEntry> entries = dimension.getCarving();
|
List<IrisDimensionCarvingEntry> entries = dimension.getCarving();
|
||||||
if (entries == null || entries.isEmpty()) {
|
if (entries == null || entries.isEmpty()) {
|
||||||
resolvedState.rootEntriesByWorldY.put(worldY, null);
|
resolvedState.rememberRoot(worldY, null);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +105,7 @@ public final class IrisDimensionCarvingResolver {
|
|||||||
resolved = entry;
|
resolved = entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
resolvedState.rootEntriesByWorldY.put(worldY, resolved);
|
resolvedState.rememberRoot(worldY, resolved);
|
||||||
return resolved;
|
return resolved;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,8 +325,9 @@ public final class IrisDimensionCarvingResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public IrisBiome resolveBiome(int worldX, int worldY, int worldZ) {
|
public IrisBiome resolveBiome(int worldX, int worldY, int worldZ) {
|
||||||
IrisDimensionCarvingEntry root = state.rootEntriesByWorldY.containsKey(worldY)
|
int slot = state.rootSlot(worldY);
|
||||||
? state.rootEntriesByWorldY.get(worldY)
|
IrisDimensionCarvingEntry root = slot >= 0
|
||||||
|
? state.roots[slot]
|
||||||
: selectBoundRootEntry(dimension, worldY, data, state);
|
: selectBoundRootEntry(dimension, worldY, data, state);
|
||||||
if (root == null) {
|
if (root == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -336,7 +338,11 @@ public final class IrisDimensionCarvingResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final class State {
|
public static final class State {
|
||||||
private final Map<Integer, IrisDimensionCarvingEntry> rootEntriesByWorldY = new HashMap<>();
|
private static final int ROOT_SLOTS = 512;
|
||||||
|
|
||||||
|
private int[] rootWorldYs;
|
||||||
|
private IrisDimensionCarvingEntry[] roots;
|
||||||
|
private boolean[] rootsKnown;
|
||||||
private final Map<IrisDimensionCarvingEntry, IrisRaritySelection<CarvingChoice>> selectionPlans = new IdentityHashMap<>();
|
private final Map<IrisDimensionCarvingEntry, IrisRaritySelection<CarvingChoice>> selectionPlans = new IdentityHashMap<>();
|
||||||
private final Map<IrisDimensionCarvingEntry, IrisBiome> biomeCache = new IdentityHashMap<>();
|
private final Map<IrisDimensionCarvingEntry, IrisBiome> biomeCache = new IdentityHashMap<>();
|
||||||
private WeakReference<Engine> engineIdentity;
|
private WeakReference<Engine> engineIdentity;
|
||||||
@@ -357,7 +363,10 @@ public final class IrisDimensionCarvingResolver {
|
|||||||
engineIdentity = new WeakReference<>(engine);
|
engineIdentity = new WeakReference<>(engine);
|
||||||
dimensionIdentity = new WeakReference<>(dimension);
|
dimensionIdentity = new WeakReference<>(dimension);
|
||||||
dataIdentity = new WeakReference<>(data);
|
dataIdentity = new WeakReference<>(data);
|
||||||
rootEntriesByWorldY.clear();
|
if (rootsKnown != null) {
|
||||||
|
Arrays.fill(rootsKnown, false);
|
||||||
|
Arrays.fill(roots, null);
|
||||||
|
}
|
||||||
selectionPlans.clear();
|
selectionPlans.clear();
|
||||||
biomeCache.clear();
|
biomeCache.clear();
|
||||||
entryIndex = null;
|
entryIndex = null;
|
||||||
@@ -366,6 +375,23 @@ public final class IrisDimensionCarvingResolver {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int rootSlot(int worldY) {
|
||||||
|
int slot = worldY & (ROOT_SLOTS - 1);
|
||||||
|
return rootsKnown != null && rootsKnown[slot] && rootWorldYs[slot] == worldY ? slot : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rememberRoot(int worldY, IrisDimensionCarvingEntry root) {
|
||||||
|
if (rootsKnown == null) {
|
||||||
|
rootWorldYs = new int[ROOT_SLOTS];
|
||||||
|
roots = new IrisDimensionCarvingEntry[ROOT_SLOTS];
|
||||||
|
rootsKnown = new boolean[ROOT_SLOTS];
|
||||||
|
}
|
||||||
|
int slot = worldY & (ROOT_SLOTS - 1);
|
||||||
|
rootWorldYs[slot] = worldY;
|
||||||
|
roots[slot] = root;
|
||||||
|
rootsKnown[slot] = true;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean references(WeakReference<?> identity, Object value) {
|
private static boolean references(WeakReference<?> identity, Object value) {
|
||||||
return identity != null && identity.get() == value;
|
return identity != null && identity.get() == value;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -227,12 +227,12 @@ public final class GenerationSemanticCapture {
|
|||||||
}
|
}
|
||||||
resolvedCaves.set(position);
|
resolvedCaves.set(position);
|
||||||
if (explicitBiomeKey != null && !explicitBiomeKey.isBlank()) {
|
if (explicitBiomeKey != null && !explicitBiomeKey.isBlank()) {
|
||||||
semantics.addCaveBiome(explicitBiomeKey);
|
caveBiomes.add(semantics, explicitBiomeKey);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
IrisBiome caveBiome = caveBiomes.resolve(blockX, y, blockZ);
|
IrisBiome caveBiome = caveBiomes.resolve(blockX, y, blockZ);
|
||||||
if (caveBiome != null && caveBiome.getLoadKey() != null) {
|
if (caveBiome != null && caveBiome.getLoadKey() != null) {
|
||||||
semantics.addCaveBiome(caveBiome.getLoadKey());
|
caveBiomes.add(semantics, caveBiome.getLoadKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,6 +280,7 @@ public final class GenerationSemanticCapture {
|
|||||||
private final IrisDimensionCarvingResolver.State fallbackState = new IrisDimensionCarvingResolver.State();
|
private final IrisDimensionCarvingResolver.State fallbackState = new IrisDimensionCarvingResolver.State();
|
||||||
private IrisDimensionCarvingResolver.Snapshot snapshot;
|
private IrisDimensionCarvingResolver.Snapshot snapshot;
|
||||||
private int minimumY;
|
private int minimumY;
|
||||||
|
private String lastKey;
|
||||||
|
|
||||||
private CaveBiomes(Engine engine, boolean scoped) {
|
private CaveBiomes(Engine engine, boolean scoped) {
|
||||||
this.engine = engine;
|
this.engine = engine;
|
||||||
@@ -290,6 +291,13 @@ public final class GenerationSemanticCapture {
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void add(ChunkGenerationSemantics.Builder semantics, String key) {
|
||||||
|
if (key != lastKey) {
|
||||||
|
semantics.addCaveBiome(key);
|
||||||
|
lastKey = key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IrisBiome resolve(int x, int y, int z) {
|
private IrisBiome resolve(int x, int y, int z) {
|
||||||
if (!scoped) {
|
if (!scoped) {
|
||||||
return engine.getCaveBiome(x, y, z);
|
return engine.getCaveBiome(x, y, z);
|
||||||
|
|||||||
+3
-4
@@ -494,12 +494,11 @@ public class IrisDimensionCarvingResolverParityTest {
|
|||||||
assertSame(fixture.entry(), IrisDimensionCarvingResolver.resolveRootEntry(
|
assertSame(fixture.entry(), IrisDimensionCarvingResolver.resolveRootEntry(
|
||||||
fixture.engine(), 80, state));
|
fixture.engine(), 80, state));
|
||||||
|
|
||||||
Field rootEntriesField = IrisDimensionCarvingResolver.State.class
|
Field rootsField = IrisDimensionCarvingResolver.State.class.getDeclaredField("roots");
|
||||||
.getDeclaredField("rootEntriesByWorldY");
|
rootsField.setAccessible(true);
|
||||||
rootEntriesField.setAccessible(true);
|
|
||||||
System.gc();
|
System.gc();
|
||||||
|
|
||||||
assertSame(fixture.entry(), ((Map<?, ?>) rootEntriesField.get(state)).get(80));
|
assertSame(fixture.entry(), ((IrisDimensionCarvingEntry[]) rootsField.get(state))[80]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private RetainedFixture createRetainedFixture() {
|
private RetainedFixture createRetainedFixture() {
|
||||||
|
|||||||
Reference in new issue
Block a user