mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-03 08:25:31 +00:00
drastically optimize ChunkInterpolator
This commit is contained in:
parent
012209cfcf
commit
b62c4d742f
@ -6,6 +6,7 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
|
||||
|
||||
import com.dfsek.terra.api.config.meta.Meta;
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
||||
|
||||
|
||||
public class BiomeNoiseConfigTemplate implements ObjectTemplate<BiomeNoiseProperties> {
|
||||
@ -39,6 +40,6 @@ public class BiomeNoiseConfigTemplate implements ObjectTemplate<BiomeNoiseProper
|
||||
@Override
|
||||
public BiomeNoiseProperties get() {
|
||||
return new BiomeNoiseProperties(baseSampler, elevationSampler, carvingSampler, blendDistance, blendStep, blendWeight,
|
||||
elevationWeight);
|
||||
elevationWeight, new ThreadLocalNoiseHolder());
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.dfsek.terra.addons.chunkgenerator.config.noise;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
import com.dfsek.terra.api.properties.Properties;
|
||||
import com.dfsek.terra.api.util.mutable.MutableInteger;
|
||||
|
||||
|
||||
public record BiomeNoiseProperties(NoiseSampler base,
|
||||
@ -10,6 +11,6 @@ public record BiomeNoiseProperties(NoiseSampler base,
|
||||
int blendDistance,
|
||||
int blendStep,
|
||||
double blendWeight,
|
||||
double elevationWeight) implements Properties {
|
||||
|
||||
double elevationWeight,
|
||||
ThreadLocalNoiseHolder noiseHolder) implements Properties {
|
||||
}
|
||||
|
@ -0,0 +1,32 @@
|
||||
package com.dfsek.terra.addons.chunkgenerator.config.noise;
|
||||
|
||||
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||
|
||||
|
||||
public class ThreadLocalNoiseHolder {
|
||||
private final ThreadLocal<Holder> holder = ThreadLocal.withInitial(Holder::new);
|
||||
|
||||
public double getNoise(NoiseSampler sampler, int x, int y, int z, long seed) {
|
||||
Holder holder = this.holder.get();
|
||||
|
||||
if(holder.init && holder.y == y && holder.z == z && holder.x == x && holder.seed == seed) {
|
||||
return holder.noise;
|
||||
}
|
||||
|
||||
double noise = sampler.noise(seed, x, y, z);
|
||||
holder.noise = noise;
|
||||
holder.x = x;
|
||||
holder.y = y;
|
||||
holder.z = z;
|
||||
holder.seed = seed;
|
||||
holder.init = true;
|
||||
return noise;
|
||||
}
|
||||
|
||||
private static final class Holder {
|
||||
int x, y, z;
|
||||
boolean init = false;
|
||||
long seed;
|
||||
double noise;
|
||||
}
|
||||
}
|
@ -25,7 +25,6 @@ import java.util.Map;
|
||||
*/
|
||||
public class ChunkInterpolator {
|
||||
private final Interpolator3[][][] interpGrid;
|
||||
private final long seed;
|
||||
|
||||
private final int min;
|
||||
private final int max;
|
||||
@ -42,8 +41,7 @@ public class ChunkInterpolator {
|
||||
public ChunkInterpolator(long seed, int chunkX, int chunkZ, BiomeProvider provider, int min, int max) {
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
this.seed = seed;
|
||||
|
||||
|
||||
int xOrigin = chunkX << 4;
|
||||
int zOrigin = chunkZ << 4;
|
||||
|
||||
@ -65,23 +63,29 @@ public class ChunkInterpolator {
|
||||
for(int y = 0; y < size; y++) {
|
||||
int scaledY = (y << 2) + min;
|
||||
BiomeNoiseProperties generationSettings = column.get(scaledY)
|
||||
.getContext()
|
||||
.get(BiomeNoiseProperties.class);
|
||||
Map<BiomeNoiseProperties, MutableInteger> genMap = new HashMap<>();
|
||||
.getContext()
|
||||
.get(BiomeNoiseProperties.class);
|
||||
|
||||
int step = generationSettings.blendStep();
|
||||
int blend = generationSettings.blendDistance();
|
||||
|
||||
double runningNoise = 0;
|
||||
double runningDiv = 0;
|
||||
|
||||
for(int xi = -blend; xi <= blend; xi++) {
|
||||
for(int zi = -blend; zi <= blend; zi++) {
|
||||
genMap.computeIfAbsent(
|
||||
provider.getBiome(absoluteX + (xi * step), scaledY, absoluteZ + (zi * step), seed)
|
||||
.getContext()
|
||||
.get(BiomeNoiseProperties.class),
|
||||
g -> new MutableInteger(0)).increment(); // Increment by 1
|
||||
BiomeNoiseProperties properties = provider
|
||||
.getBiome(absoluteX + (xi * step), scaledY, absoluteZ + (zi * step), seed)
|
||||
.getContext()
|
||||
.get(BiomeNoiseProperties.class);
|
||||
double sample = properties.noiseHolder().getNoise(properties.base(), absoluteX, scaledY, absoluteZ, seed);
|
||||
runningNoise += sample * properties.blendWeight();
|
||||
runningDiv += properties.blendWeight();
|
||||
}
|
||||
}
|
||||
double noise = computeNoise(genMap, absoluteX, scaledY, absoluteZ);
|
||||
|
||||
double noise = runningNoise / runningDiv;
|
||||
|
||||
noiseStorage[x][z][y] = noise;
|
||||
if(y == size - 1) {
|
||||
noiseStorage[x][z][size] = noise;
|
||||
@ -111,24 +115,6 @@ public class ChunkInterpolator {
|
||||
return FastMath.max(FastMath.min(value, high), 0);
|
||||
}
|
||||
|
||||
public double computeNoise(BiomeNoiseProperties generationSettings, double x, double y, double z) {
|
||||
return generationSettings.base().noise(seed, x, y, z);
|
||||
}
|
||||
|
||||
public double computeNoise(Map<BiomeNoiseProperties, MutableInteger> gens, double x, double y, double z) {
|
||||
double n = 0;
|
||||
double div = 0;
|
||||
for(Map.Entry<BiomeNoiseProperties, MutableInteger> entry : gens.entrySet()) {
|
||||
BiomeNoiseProperties gen = entry.getKey();
|
||||
int weight = entry.getValue().get();
|
||||
double noise = computeNoise(gen, x, y, z);
|
||||
|
||||
n += noise * weight;
|
||||
div += gen.blendWeight() * weight;
|
||||
}
|
||||
return n / div;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the noise at a pair of internal chunk coordinates.
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user