Improve biome generator performance when interpolators match each other

This commit is contained in:
cyberpwn
2021-09-12 07:46:24 -04:00
parent 7d0555fb67
commit cd7f192fba
3 changed files with 32 additions and 19 deletions
@@ -35,8 +35,6 @@ import java.util.function.Supplier;
public class IrisAPI public class IrisAPI
{ {
private static final AtomicCache<RegistryHolder<Supplier<BlockData>>> customBlock = new AtomicCache<>(); private static final AtomicCache<RegistryHolder<Supplier<BlockData>>> customBlock = new AtomicCache<>();
private static final AtomicCache<RegistryHolder<AwareBlockMirror>> customAwareBlock = new AtomicCache<>();
private static final AtomicCache<RegistryHolder<APIWorldBlock>> customWorldBlock = new AtomicCache<>();
/** /**
* Checks if the given world is an Iris World * Checks if the given world is an Iris World
@@ -30,9 +30,11 @@ import com.volmit.iris.engine.object.IrisDecorationPart;
import com.volmit.iris.engine.object.IrisDecorator; import com.volmit.iris.engine.object.IrisDecorator;
import com.volmit.iris.engine.object.IrisFeaturePositional; import com.volmit.iris.engine.object.IrisFeaturePositional;
import com.volmit.iris.engine.object.IrisGenerator; import com.volmit.iris.engine.object.IrisGenerator;
import com.volmit.iris.engine.object.IrisInterpolator;
import com.volmit.iris.engine.object.IrisRegion; import com.volmit.iris.engine.object.IrisRegion;
import com.volmit.iris.util.collection.KList; import com.volmit.iris.util.collection.KList;
import com.volmit.iris.util.collection.KMap; import com.volmit.iris.util.collection.KMap;
import com.volmit.iris.util.collection.KSet;
import com.volmit.iris.util.data.DataProvider; import com.volmit.iris.util.data.DataProvider;
import com.volmit.iris.util.math.M; import com.volmit.iris.util.math.M;
import com.volmit.iris.util.math.RNG; import com.volmit.iris.util.math.RNG;
@@ -52,7 +54,7 @@ public class IrisComplex implements DataProvider {
private RNG rng; private RNG rng;
private double fluidHeight; private double fluidHeight;
private IrisData data; private IrisData data;
private KList<IrisGenerator> generators; private KMap<IrisInterpolator, KSet<IrisGenerator>> generators;
private ProceduralStream<IrisRegion> regionStream; private ProceduralStream<IrisRegion> regionStream;
private ProceduralStream<Double> regionStyleStream; private ProceduralStream<Double> regionStyleStream;
private ProceduralStream<Double> regionIdentityStream; private ProceduralStream<Double> regionIdentityStream;
@@ -100,7 +102,7 @@ public class IrisComplex implements DataProvider {
this.data = engine.getData(); this.data = engine.getData();
double height = engine.getHeight(); double height = engine.getHeight();
fluidHeight = engine.getDimension().getFluidHeight(); fluidHeight = engine.getDimension().getFluidHeight();
generators = new KList<>(); generators = new KMap<>();
focus = engine.getFocus(); focus = engine.getFocus();
KMap<InferredType, ProceduralStream<IrisBiome>> inferredStreams = new KMap<>(); KMap<InferredType, ProceduralStream<IrisBiome>> inferredStreams = new KMap<>();
@@ -373,28 +375,41 @@ public class IrisComplex implements DataProvider {
return biome; return biome;
} }
private double getHeight(Engine engine, IrisBiome b, double x, double z, long seed, boolean features) { private double getInterpolatedHeight(Engine engine, double x, double z, long seed)
{
double h = 0; double h = 0;
for (IrisGenerator gen : generators) { for (IrisInterpolator i : generators.keySet()) {
h += gen.getInterpolator().interpolate(x, z, (xx, zz) -> h += i.interpolate(x, z, (xx, zz) ->
{ {
try { try {
IrisBiome bx = baseBiomeStream.get(xx, zz); IrisBiome bx = baseBiomeStream.get(xx, zz);
double b = 0;
return M.lerp(bx.getGenLinkMin(gen.getLoadKey()), for(IrisGenerator gen : generators.get(i))
bx.getGenLinkMax(gen.getLoadKey()), {
gen.getHeight(x, z, seed + 239945)); b += M.lerp(bx.getGenLinkMin(gen.getLoadKey()),
bx.getGenLinkMax(gen.getLoadKey()),
gen.getHeight(x, z, seed + 239945));
}
return b;
} catch (Throwable e) { } catch (Throwable e) {
Iris.reportError(e); Iris.reportError(e);
e.printStackTrace(); e.printStackTrace();
Iris.warn("Failed to sample hi biome at " + xx + " " + zz + " using the generator " + gen.getLoadKey()); Iris.error("Failed to sample hi biome at " + xx + " " + zz + "...");
} }
return 0; return 0;
}); });
} }
return h;
}
private double getHeight(Engine engine, IrisBiome b, double x, double z, long seed, boolean features) {
double h = getInterpolatedHeight(engine, x, z, seed);
AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z)); AtomicDouble noise = new AtomicDouble(h + fluidHeight + overlayStream.get(x, z));
if (features) { if (features) {
@@ -407,13 +422,7 @@ public class IrisComplex implements DataProvider {
} }
private void registerGenerator(IrisGenerator cachedGenerator) { private void registerGenerator(IrisGenerator cachedGenerator) {
for (IrisGenerator i : generators) { generators.computeIfAbsent(cachedGenerator.getInterpolator(), (k) -> new KSet<>()).add(cachedGenerator);
if (i.getLoadKey().equals(cachedGenerator.getLoadKey())) {
return;
}
}
generators.add(cachedGenerator);
} }
private IrisBiome implode(IrisBiome b, Double x, Double z) { private IrisBiome implode(IrisBiome b, Double x, Double z) {
@@ -31,7 +31,8 @@ import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
@Snippet("interpolator") import java.util.Objects;
@Accessors(chain = true) @Accessors(chain = true)
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@@ -50,6 +51,11 @@ public class IrisInterpolator {
@Desc("The range checked horizontally. Smaller ranges yeild more detail but are not as smooth.") @Desc("The range checked horizontally. Smaller ranges yeild more detail but are not as smooth.")
private double horizontalScale = 7; private double horizontalScale = 7;
public int hashCode()
{
return Objects.hash(horizontalScale, function);
}
public double interpolate(double x, double z, NoiseProvider provider) { public double interpolate(double x, double z, NoiseProvider provider) {
return interpolate((int) Math.round(x), (int) Math.round(z), provider); return interpolate((int) Math.round(x), (int) Math.round(z), provider);
} }