drastically optimize ChunkInterpolator

This commit is contained in:
dfsek 2022-06-13 22:39:39 -07:00
parent 012209cfcf
commit b62c4d742f
4 changed files with 53 additions and 33 deletions

View File

@ -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.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.mutable.MutableInteger;
public class BiomeNoiseConfigTemplate implements ObjectTemplate<BiomeNoiseProperties> { public class BiomeNoiseConfigTemplate implements ObjectTemplate<BiomeNoiseProperties> {
@ -39,6 +40,6 @@ public class BiomeNoiseConfigTemplate implements ObjectTemplate<BiomeNoiseProper
@Override @Override
public BiomeNoiseProperties get() { public BiomeNoiseProperties get() {
return new BiomeNoiseProperties(baseSampler, elevationSampler, carvingSampler, blendDistance, blendStep, blendWeight, return new BiomeNoiseProperties(baseSampler, elevationSampler, carvingSampler, blendDistance, blendStep, blendWeight,
elevationWeight); elevationWeight, new ThreadLocalNoiseHolder());
} }
} }

View File

@ -2,6 +2,7 @@ package com.dfsek.terra.addons.chunkgenerator.config.noise;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.properties.Properties; import com.dfsek.terra.api.properties.Properties;
import com.dfsek.terra.api.util.mutable.MutableInteger;
public record BiomeNoiseProperties(NoiseSampler base, public record BiomeNoiseProperties(NoiseSampler base,
@ -10,6 +11,6 @@ public record BiomeNoiseProperties(NoiseSampler base,
int blendDistance, int blendDistance,
int blendStep, int blendStep,
double blendWeight, double blendWeight,
double elevationWeight) implements Properties { double elevationWeight,
ThreadLocalNoiseHolder noiseHolder) implements Properties {
} }

View File

@ -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;
}
}

View File

@ -25,7 +25,6 @@ import java.util.Map;
*/ */
public class ChunkInterpolator { public class ChunkInterpolator {
private final Interpolator3[][][] interpGrid; private final Interpolator3[][][] interpGrid;
private final long seed;
private final int min; private final int min;
private final int max; private final int max;
@ -42,7 +41,6 @@ public class ChunkInterpolator {
public ChunkInterpolator(long seed, int chunkX, int chunkZ, BiomeProvider provider, int min, int max) { public ChunkInterpolator(long seed, int chunkX, int chunkZ, BiomeProvider provider, int min, int max) {
this.min = min; this.min = min;
this.max = max; this.max = max;
this.seed = seed;
int xOrigin = chunkX << 4; int xOrigin = chunkX << 4;
int zOrigin = chunkZ << 4; int zOrigin = chunkZ << 4;
@ -67,21 +65,27 @@ public class ChunkInterpolator {
BiomeNoiseProperties generationSettings = column.get(scaledY) BiomeNoiseProperties generationSettings = column.get(scaledY)
.getContext() .getContext()
.get(BiomeNoiseProperties.class); .get(BiomeNoiseProperties.class);
Map<BiomeNoiseProperties, MutableInteger> genMap = new HashMap<>();
int step = generationSettings.blendStep(); int step = generationSettings.blendStep();
int blend = generationSettings.blendDistance(); int blend = generationSettings.blendDistance();
double runningNoise = 0;
double runningDiv = 0;
for(int xi = -blend; xi <= blend; xi++) { for(int xi = -blend; xi <= blend; xi++) {
for(int zi = -blend; zi <= blend; zi++) { for(int zi = -blend; zi <= blend; zi++) {
genMap.computeIfAbsent( BiomeNoiseProperties properties = provider
provider.getBiome(absoluteX + (xi * step), scaledY, absoluteZ + (zi * step), seed) .getBiome(absoluteX + (xi * step), scaledY, absoluteZ + (zi * step), seed)
.getContext() .getContext()
.get(BiomeNoiseProperties.class), .get(BiomeNoiseProperties.class);
g -> new MutableInteger(0)).increment(); // Increment by 1 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; noiseStorage[x][z][y] = noise;
if(y == size - 1) { if(y == size - 1) {
noiseStorage[x][z][size] = noise; noiseStorage[x][z][size] = noise;
@ -111,24 +115,6 @@ public class ChunkInterpolator {
return FastMath.max(FastMath.min(value, high), 0); 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. * Gets the noise at a pair of internal chunk coordinates.
* *