mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2026-02-16 02:20:57 +00:00
More Extrusion Opts
This commit is contained in:
@@ -10,7 +10,7 @@ object Versions {
|
||||
const val tectonic = "4.3.1"
|
||||
const val paralithic = "2.0.1"
|
||||
const val strata = "1.3.2"
|
||||
const val seismic = "2.5.0"
|
||||
const val seismic = "2.5.1"
|
||||
|
||||
const val cloud = "2.0.0"
|
||||
|
||||
|
||||
@@ -46,6 +46,6 @@ class BaseBiomeColumn implements Column<Biome> {
|
||||
|
||||
@Override
|
||||
public Biome get(int y) {
|
||||
return biomeProvider.extrude(base, x, y, z, seed);
|
||||
return biomeProvider.pipeline.extrude(base, x, y, z, seed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,15 +6,17 @@ import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||
import com.dfsek.terra.addons.biome.extrusion.utils.ExtrusionPipeline;
|
||||
import com.dfsek.terra.addons.biome.extrusion.utils.ExtrusionPipelineFactory;
|
||||
import com.dfsek.terra.api.util.Column;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
import com.dfsek.terra.api.world.biome.generation.BiomeProvider;
|
||||
|
||||
|
||||
public class BiomeExtrusionProvider implements BiomeProvider {
|
||||
public final ExtrusionPipeline pipeline;
|
||||
private final BiomeProvider delegate;
|
||||
private final Set<Biome> biomes;
|
||||
private final ExtrusionPipeline pipeline;
|
||||
private final int resolution;
|
||||
|
||||
public BiomeExtrusionProvider(BiomeProvider delegate, List<Extrusion> extrusions, int resolution) {
|
||||
@@ -30,11 +32,7 @@ public class BiomeExtrusionProvider implements BiomeProvider {
|
||||
@Override
|
||||
public Biome getBiome(int x, int y, int z, long seed) {
|
||||
Biome delegated = delegate.getBiome(x, y, z, seed);
|
||||
return extrude(delegated, x, y, z, seed);
|
||||
}
|
||||
|
||||
public Biome extrude(Biome original, int x, int y, int z, long seed) {
|
||||
return pipeline.extrude(original, x, y, z, seed);
|
||||
return pipeline.extrude(delegated, x, y, z, seed);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,43 +1,64 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion.extrusions;
|
||||
|
||||
import com.dfsek.seismic.type.sampler.Sampler;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import com.dfsek.terra.addons.biome.extrusion.api.Extrusion;
|
||||
import com.dfsek.terra.addons.biome.extrusion.api.ReplaceableBiome;
|
||||
import com.dfsek.terra.addons.biome.query.api.BiomeQueries;
|
||||
import com.dfsek.terra.api.util.collection.ProbabilityCollection;
|
||||
import com.dfsek.terra.api.util.collection.TriStateIntCache;
|
||||
import com.dfsek.terra.api.util.range.Range;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.concurrent.atomic.AtomicLongArray;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Sets biomes at locations based on a sampler.
|
||||
*/
|
||||
public class ReplaceExtrusion implements Extrusion {
|
||||
private final Sampler sampler;
|
||||
|
||||
private final Range range;
|
||||
|
||||
private final ProbabilityCollection<ReplaceableBiome> biomes;
|
||||
|
||||
private final Predicate<Biome> hasTag;
|
||||
|
||||
// Replaced ThreadLocal<HashMap> with a specialized primitive cache.
|
||||
// Shared across all threads safely.
|
||||
private final TriStateIntCache cache;
|
||||
|
||||
public ReplaceExtrusion(Sampler sampler, Range range, ProbabilityCollection<ReplaceableBiome> biomes, String tag) {
|
||||
this.sampler = sampler;
|
||||
this.range = range;
|
||||
this.biomes = biomes;
|
||||
this.hasTag = BiomeQueries.has(tag);
|
||||
|
||||
this.cache = new TriStateIntCache(65536);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome extrude(Biome original, int x, int y, int z, long seed) {
|
||||
if(hasTag.test(original)) {
|
||||
return range.ifInRange(y, () -> biomes.get(sampler, x, y, z, seed).get(original), original);
|
||||
int id = original.getIntID();
|
||||
|
||||
long state = cache.get(id);
|
||||
boolean passes;
|
||||
|
||||
if (state == TriStateIntCache.STATE_UNSET) {
|
||||
// Only run the test if unset in cache
|
||||
passes = hasTag.test(original);
|
||||
cache.set(id, passes);
|
||||
} else {
|
||||
// Read the primitive long directly
|
||||
passes = (state == TriStateIntCache.STATE_TRUE);
|
||||
}
|
||||
|
||||
if (passes) {
|
||||
if (range.isInRange(y)) {
|
||||
return biomes.get(sampler, x, y, z, seed).get(original);
|
||||
}
|
||||
}
|
||||
|
||||
return original;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion;
|
||||
package com.dfsek.terra.addons.biome.extrusion.utils;
|
||||
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.dfsek.terra.addons.biome.extrusion;
|
||||
package com.dfsek.terra.addons.biome.extrusion.utils;
|
||||
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
@@ -8,6 +8,7 @@
|
||||
package com.dfsek.terra.addons.biome;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import com.dfsek.terra.api.properties.Context;
|
||||
import com.dfsek.terra.api.world.biome.Biome;
|
||||
@@ -18,6 +19,7 @@ import com.dfsek.terra.api.world.biome.PlatformBiome;
|
||||
* Class representing a config-defined biome
|
||||
*/
|
||||
public class UserDefinedBiome implements Biome {
|
||||
private final static AtomicInteger INT_ID_COUNTER = new AtomicInteger(0);
|
||||
private final PlatformBiome vanilla;
|
||||
private final String id;
|
||||
private final BiomeTemplate config;
|
||||
@@ -25,6 +27,7 @@ public class UserDefinedBiome implements Biome {
|
||||
private final Set<String> tags;
|
||||
|
||||
private final Context context = new Context();
|
||||
private final int intID;
|
||||
|
||||
public UserDefinedBiome(PlatformBiome vanilla, BiomeTemplate config) {
|
||||
this.vanilla = vanilla;
|
||||
@@ -32,6 +35,7 @@ public class UserDefinedBiome implements Biome {
|
||||
this.config = config;
|
||||
this.color = config.getColor();
|
||||
this.tags = config.getTags();
|
||||
this.intID = INT_ID_COUNTER.getAndIncrement();
|
||||
tags.add("BIOME:" + id);
|
||||
tags.add("ALL");
|
||||
}
|
||||
@@ -61,6 +65,11 @@ public class UserDefinedBiome implements Biome {
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIntID() {
|
||||
return intID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getID() {
|
||||
return id;
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.dfsek.terra.api.util.collection;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicLongArray;
|
||||
|
||||
public class TriStateIntCache {
|
||||
public static final long STATE_UNSET = 0L;
|
||||
public static final long STATE_FALSE = 1L;
|
||||
public static final long STATE_TRUE = 2L;
|
||||
|
||||
private static final long BIT_MASK = 3L;
|
||||
private final AtomicLongArray data;
|
||||
|
||||
public TriStateIntCache(int maxKeySize) {
|
||||
this.data = new AtomicLongArray((maxKeySize + 31) >>> 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the cache state without any allocation.
|
||||
* @return STATE_UNSET (0), STATE_FALSE (1), or STATE_TRUE (2)
|
||||
*/
|
||||
public long get(int key) {
|
||||
int arrayIndex = key >>> 5;
|
||||
int bitShift = (key & 31) << 1;
|
||||
long currentWord = data.get(arrayIndex);
|
||||
return (currentWord >>> bitShift) & BIT_MASK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value safely. Handles race conditions internally.
|
||||
*/
|
||||
public void set(int key, boolean value) {
|
||||
int arrayIndex = key >>> 5;
|
||||
int bitShift = (key & 31) << 1;
|
||||
long targetState = value ? STATE_TRUE : STATE_FALSE;
|
||||
|
||||
long currentWord, newWord;
|
||||
do {
|
||||
currentWord = data.get(arrayIndex);
|
||||
|
||||
// Race condition check:
|
||||
long existingState = (currentWord >>> bitShift) & BIT_MASK;
|
||||
if (existingState != STATE_UNSET) {
|
||||
return; // Already set, abort our update
|
||||
}
|
||||
|
||||
// Create new word with our bit set
|
||||
newWord = (currentWord & ~(BIT_MASK << bitShift)) | (targetState << bitShift);
|
||||
|
||||
} while (!data.compareAndSet(arrayIndex, currentWord, newWord));
|
||||
}
|
||||
}
|
||||
@@ -39,4 +39,12 @@ public interface Biome extends PropertyHolder, StringIdentifiable {
|
||||
* @return A {@link Set} of String tags this biome holds.
|
||||
*/
|
||||
Set<String> getTags();
|
||||
|
||||
|
||||
/**
|
||||
* Get the numeric ID of this biome, generated at registration time
|
||||
*
|
||||
* @return The numeric ID.
|
||||
*/
|
||||
int getIntID();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user