noise function metavalues

This commit is contained in:
dfsek
2021-06-14 01:44:19 -07:00
parent df45aecdab
commit 78991c667c
8 changed files with 53 additions and 43 deletions
@@ -15,4 +15,8 @@ public final class MapUtil {
public static <K1, V1, K2, V2> Map<K2, V2> remap(Function<K1, K2> keys, Function<V1, V2> values, Map<K1, V1> in) { public static <K1, V1, K2, V2> Map<K2, V2> remap(Function<K1, K2> keys, Function<V1, V2> values, Map<K1, V1> in) {
return remap(keys, values, in, HashMap::new); return remap(keys, values, in, HashMap::new);
} }
public static <K, V1, V2> Map<K, V2> remapValues(Function<V1, V2> values, Map<K, V1> in) {
return remap(Function.identity(), values, in);
}
} }
@@ -2,6 +2,7 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise;
import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.config.meta.MetaValue;
import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.CellularSampler; import com.dfsek.terra.api.math.noise.samplers.noise.CellularSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.simplex.OpenSimplex2Sampler; import com.dfsek.terra.api.math.noise.samplers.noise.simplex.OpenSimplex2Sampler;
@@ -11,20 +12,20 @@ import com.dfsek.terra.api.util.seeded.NoiseSeeded;
public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> { public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
@Value("distance") @Value("distance")
@Default @Default
private CellularSampler.DistanceFunction cellularDistanceFunction = CellularSampler.DistanceFunction.EuclideanSq; private MetaValue<CellularSampler.DistanceFunction> cellularDistanceFunction = MetaValue.of(CellularSampler.DistanceFunction.EuclideanSq);
@Value("return") @Value("return")
@Default @Default
private CellularSampler.ReturnType cellularReturnType = CellularSampler.ReturnType.Distance; private MetaValue<CellularSampler.ReturnType> cellularReturnType = MetaValue.of(CellularSampler.ReturnType.Distance);
@Value("jitter") @Value("jitter")
@Default @Default
private double cellularJitter = 1.0D; private MetaValue<Double> cellularJitter = MetaValue.of(1.0D);
@Value("lookup") @Value("lookup")
@Default @Default
private NoiseSeeded lookup = new NoiseSeeded() { private MetaValue<NoiseSeeded> lookup = MetaValue.of(new NoiseSeeded() {
@Override @Override
public NoiseSampler apply(Long seed) { public NoiseSampler apply(Long seed) {
@@ -35,16 +36,16 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
public int getDimensions() { public int getDimensions() {
return 2; return 2;
} }
}; });
@Override @Override
public NoiseSampler apply(Long seed) { public NoiseSampler apply(Long seed) {
CellularSampler sampler = new CellularSampler((int) (long) seed + salt); CellularSampler sampler = new CellularSampler((int) (long) seed + salt.get());
sampler.setNoiseLookup(lookup.apply(seed)); sampler.setNoiseLookup(lookup.get().apply(seed));
sampler.setFrequency(frequency); sampler.setFrequency(frequency.get());
sampler.setJitterModifier(cellularJitter); sampler.setJitterModifier(cellularJitter.get());
sampler.setReturnType(cellularReturnType); sampler.setReturnType(cellularReturnType.get());
sampler.setDistanceFunction(cellularDistanceFunction); sampler.setDistanceFunction(cellularDistanceFunction.get());
return sampler; return sampler;
} }
} }
@@ -2,6 +2,7 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise;
import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.config.meta.MetaValue;
import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler; import com.dfsek.terra.api.math.noise.samplers.noise.ConstantSampler;
import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate;
@@ -10,10 +11,10 @@ import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate;
public class ConstantNoiseTemplate extends SamplerTemplate<ConstantSampler> { public class ConstantNoiseTemplate extends SamplerTemplate<ConstantSampler> {
@Value("value") @Value("value")
@Default @Default
private double value = 0d; private MetaValue<Double> value = MetaValue.of(0d);
@Override @Override
public NoiseSampler apply(Long seed) { public NoiseSampler apply(Long seed) {
return new ConstantSampler(value); return new ConstantSampler(value.get());
} }
} }
@@ -8,12 +8,13 @@ import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ValidatedConfigTemplate; import com.dfsek.tectonic.config.ValidatedConfigTemplate;
import com.dfsek.tectonic.exception.ValidationException; import com.dfsek.tectonic.exception.ValidationException;
import com.dfsek.terra.api.config.meta.MetaValue;
import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.ExpressionFunction; import com.dfsek.terra.api.math.noise.samplers.noise.ExpressionFunction;
import com.dfsek.terra.api.math.paralithic.BlankFunction;
import com.dfsek.terra.api.math.paralithic.defined.UserDefinedFunction; import com.dfsek.terra.api.math.paralithic.defined.UserDefinedFunction;
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction2; import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction2;
import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction3; import com.dfsek.terra.api.math.paralithic.noise.NoiseFunction3;
import com.dfsek.terra.api.util.MapUtil;
import com.dfsek.terra.api.util.seeded.NoiseSeeded; import com.dfsek.terra.api.util.seeded.NoiseSeeded;
import com.dfsek.terra.config.loaders.config.function.FunctionTemplate; import com.dfsek.terra.config.loaders.config.function.FunctionTemplate;
import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate;
@@ -27,24 +28,24 @@ import java.util.Map;
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFunction> implements ValidatedConfigTemplate { public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFunction> implements ValidatedConfigTemplate {
@Value("variables") @Value("variables")
@Default @Default
private Map<String, Double> vars = new HashMap<>(); private Map<String, MetaValue<Double>> vars = new HashMap<>();
@Value("equation") @Value("equation")
private String equation; private MetaValue<String> equation;
@Value("functions") @Value("functions")
@Default @Default
private LinkedHashMap<String, NoiseSeeded> functions = new LinkedHashMap<>(); private LinkedHashMap<String, MetaValue<NoiseSeeded>> functions = new LinkedHashMap<>();
@Value("expressions") @Value("expressions")
@Default @Default
private LinkedHashMap<String, FunctionTemplate> expressions = new LinkedHashMap<>(); private LinkedHashMap<String, MetaValue<FunctionTemplate>> expressions = new LinkedHashMap<>();
@Override @Override
public NoiseSampler apply(Long seed) { public NoiseSampler apply(Long seed) {
try { try {
Map<String, Function> noiseFunctionMap = generateFunctions(seed); Map<String, Function> noiseFunctionMap = generateFunctions(seed);
return new ExpressionFunction(noiseFunctionMap, equation, vars); return new ExpressionFunction(noiseFunctionMap, equation.get(), MapUtil.remapValues(MetaValue::get, vars));
} catch(ParseException e) { } catch(ParseException e) {
throw new IllegalStateException(e); throw new IllegalStateException(e);
} }
@@ -54,7 +55,7 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
public boolean validate() throws ValidationException { public boolean validate() throws ValidationException {
try { try {
Map<String, Function> noiseFunctionMap = generateFunctions(0L); Map<String, Function> noiseFunctionMap = generateFunctions(0L);
new ExpressionFunction(noiseFunctionMap, equation, vars); new ExpressionFunction(noiseFunctionMap, equation.get(), MapUtil.remapValues(MetaValue::get, vars));
} catch(ParseException e) { } catch(ParseException e) {
throw new ValidationException("Errors occurred while parsing noise equation: ", e); throw new ValidationException("Errors occurred while parsing noise equation: ", e);
} }
@@ -64,14 +65,14 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
private Map<String, Function> generateFunctions(Long seed) throws ParseException { private Map<String, Function> generateFunctions(Long seed) throws ParseException {
Map<String, Function> noiseFunctionMap = new HashMap<>(); Map<String, Function> noiseFunctionMap = new HashMap<>();
for(Map.Entry<String, FunctionTemplate> entry : expressions.entrySet()) { for(Map.Entry<String, FunctionTemplate> entry : MapUtil.remapValues(MetaValue::get, expressions).entrySet()) {
noiseFunctionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), new Parser(), new Scope())); noiseFunctionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), new Parser(), new Scope()));
} }
functions.forEach((id, function) -> { functions.forEach((id, function) -> {
if(function.getDimensions() == 2) { if(function.get().getDimensions() == 2) {
noiseFunctionMap.put(id, new NoiseFunction2(function.apply(seed))); noiseFunctionMap.put(id, new NoiseFunction2(function.get().apply(seed)));
} else noiseFunctionMap.put(id, new NoiseFunction3(function.apply(seed))); } else noiseFunctionMap.put(id, new NoiseFunction3(function.get().apply(seed)));
}); });
return noiseFunctionMap; return noiseFunctionMap;
@@ -2,39 +2,41 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise;
import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.config.meta.MetaValue;
import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.NoiseSampler;
import com.dfsek.terra.api.math.noise.samplers.noise.GaborNoiseSampler; import com.dfsek.terra.api.math.noise.samplers.noise.GaborNoiseSampler;
@SuppressWarnings("FieldMayBeFinal")
public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> { public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
@Value("rotation") @Value("rotation")
@Default @Default
private double rotation = 0.25; private MetaValue<Double> rotation = MetaValue.of(0.25);
@Value("isotropic") @Value("isotropic")
@Default @Default
private boolean isotropic = true; private MetaValue<Boolean> isotropic = MetaValue.of(true);
@Value("deviation") @Value("deviation")
@Default @Default
private double deviation = 1.0; private MetaValue<Double> deviation = MetaValue.of(1.0);
@Value("impulses") @Value("impulses")
@Default @Default
private double impulses = 64d; private MetaValue<Double> impulses = MetaValue.of(64d);
@Value("frequency_0") @Value("frequency_0")
@Default @Default
private double f0 = 0.625; private MetaValue<Double> f0 = MetaValue.of(0.625);
@Override @Override
public NoiseSampler apply(Long seed) { public NoiseSampler apply(Long seed) {
GaborNoiseSampler gaborNoiseSampler = new GaborNoiseSampler((int) (long) seed + salt); GaborNoiseSampler gaborNoiseSampler = new GaborNoiseSampler((int) (long) seed + salt.get());
gaborNoiseSampler.setFrequency(frequency); gaborNoiseSampler.setFrequency(frequency.get());
gaborNoiseSampler.setRotation(rotation); gaborNoiseSampler.setRotation(rotation.get());
gaborNoiseSampler.setIsotropic(isotropic); gaborNoiseSampler.setIsotropic(isotropic.get());
gaborNoiseSampler.setDeviation(deviation); gaborNoiseSampler.setDeviation(deviation.get());
gaborNoiseSampler.setImpulsesPerKernel(impulses); gaborNoiseSampler.setImpulsesPerKernel(impulses.get());
gaborNoiseSampler.setFrequency0(f0); gaborNoiseSampler.setFrequency0(f0.get());
return gaborNoiseSampler; return gaborNoiseSampler;
} }
} }
@@ -2,6 +2,7 @@ package com.dfsek.terra.config.loaders.config.sampler.templates.noise;
import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value; import com.dfsek.tectonic.annotations.Value;
import com.dfsek.terra.api.config.meta.MetaValue;
import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction; import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction;
import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate;
@@ -9,9 +10,9 @@ import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate;
public abstract class NoiseTemplate<T extends NoiseFunction> extends SamplerTemplate<T> { public abstract class NoiseTemplate<T extends NoiseFunction> extends SamplerTemplate<T> {
@Value("frequency") @Value("frequency")
@Default @Default
protected double frequency = 0.02d; protected MetaValue<Double> frequency = MetaValue.of(0.02d);
@Value("salt") @Value("salt")
@Default @Default
protected int salt = 0; protected MetaValue<Integer> salt = MetaValue.of(0);
} }
@@ -14,8 +14,8 @@ public class SimpleNoiseTemplate extends NoiseTemplate<NoiseFunction> {
@Override @Override
public NoiseSampler apply(Long seed) { public NoiseSampler apply(Long seed) {
NoiseFunction sampler = samplerSupplier.apply((int) (long) seed + salt); NoiseFunction sampler = samplerSupplier.apply((int) (long) seed + salt.get());
sampler.setFrequency(frequency); sampler.setFrequency(frequency.get());
return sampler; return sampler;
} }
} }
@@ -32,7 +32,7 @@ public class ConfigPackTemplate implements ConfigTemplate {
@Value("noise") @Value("noise")
private Map<String, MetaValue<NoiseSeeded>> noiseBuilderMap; private Map<String, MetaValue<NoiseSeeded>> noiseBuilderMap;
private final Lazy<Map<String, NoiseSeeded>> lazyNoiseBuilderMap = new Lazy<>(() -> MapUtil.remap(Function.identity(), MetaValue::get, noiseBuilderMap)); private final Lazy<Map<String, NoiseSeeded>> lazyNoiseBuilderMap = new Lazy<>(() -> MapUtil.remapValues(MetaValue::get, noiseBuilderMap));
@Value("addons") @Value("addons")
@Default @Default
@@ -41,7 +41,7 @@ public class ConfigPackTemplate implements ConfigTemplate {
@Value("variables") @Value("variables")
@Default @Default
private Map<String, MetaValue<Double>> variables = new HashMap<>(); private Map<String, MetaValue<Double>> variables = new HashMap<>();
private final Lazy<Map<String, Double>> lazyVariables = new Lazy<>(() -> MapUtil.remap(Function.identity(), MetaValue::get, variables)); private final Lazy<Map<String, Double>> lazyVariables = new Lazy<>(() -> MapUtil.remapValues(MetaValue::get, variables));
@Value("beta.carving") @Value("beta.carving")
@Default @Default
@@ -55,7 +55,7 @@ public class ConfigPackTemplate implements ConfigTemplate {
@Value("structures.locatable") @Value("structures.locatable")
@Default @Default
private Map<String, MetaValue<String>> locatable = new HashMap<>(); private Map<String, MetaValue<String>> locatable = new HashMap<>();
private final Lazy<Map<String, String>> lazyLocatable = new Lazy<>(() -> MapUtil.remap(Function.identity(), MetaValue::get, locatable)); private final Lazy<Map<String, String>> lazyLocatable = new Lazy<>(() -> MapUtil.remapValues(MetaValue::get, locatable));
@Value("blend.terrain.elevation") @Value("blend.terrain.elevation")
@Default @Default