mirror of
https://github.com/PolyhedralDev/Terra.git
synced 2025-07-03 08:25:31 +00:00
Implement expression normalizer sampler
This commit is contained in:
parent
34c0895c1f
commit
1a784b51ac
@ -30,6 +30,7 @@ import com.dfsek.terra.addons.noise.config.templates.noise.fractal.BrownianMotio
|
|||||||
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.PingPongTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.PingPongTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.RidgedFractalTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.RidgedFractalTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.ClampNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.ClampNormalizerTemplate;
|
||||||
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.ExpressionNormalizerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearNormalizerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.normalizer.PosterizationNormalizerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.normalizer.PosterizationNormalizerTemplate;
|
||||||
@ -134,7 +135,7 @@ public class NoiseAddon implements AddonInitializer {
|
|||||||
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
|
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
|
||||||
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
|
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
|
||||||
noiseRegistry.register(addon.key("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions));
|
noiseRegistry.register(addon.key("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions));
|
||||||
|
noiseRegistry.register(addon.key("EXPRESSION_NORMALIZER"), () -> new ExpressionNormalizerTemplate(packSamplers, packFunctions));
|
||||||
|
|
||||||
NoiseConfigPackTemplate template = event.loadTemplate(new NoiseConfigPackTemplate());
|
NoiseConfigPackTemplate template = event.loadTemplate(new NoiseConfigPackTemplate());
|
||||||
packSamplers.putAll(template.getSamplers());
|
packSamplers.putAll(template.getSamplers());
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
package com.dfsek.terra.addons.noise.config.templates.noise;
|
package com.dfsek.terra.addons.noise.config.templates.noise;
|
||||||
|
|
||||||
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||||
import com.dfsek.paralithic.functions.Function;
|
|
||||||
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
@ -19,17 +18,16 @@ import java.util.Map;
|
|||||||
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
|
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
||||||
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
|
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
|
||||||
import com.dfsek.terra.addons.noise.paralithic.defined.UserDefinedFunction;
|
|
||||||
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2;
|
|
||||||
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
|
|
||||||
import com.dfsek.terra.addons.noise.samplers.noise.ExpressionFunction;
|
import com.dfsek.terra.addons.noise.samplers.noise.ExpressionFunction;
|
||||||
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 static com.dfsek.terra.addons.noise.paralithic.FunctionUtil.convertFunctionsAndSamplers;
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
|
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
|
||||||
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFunction> {
|
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFunction> {
|
||||||
private final Map<String, DimensionApplicableNoiseSampler> otherFunctions;
|
private final Map<String, DimensionApplicableNoiseSampler> globalSamplers;
|
||||||
private final Map<String, FunctionTemplate> globalFunctions;
|
private final Map<String, FunctionTemplate> globalFunctions;
|
||||||
@Value("variables")
|
@Value("variables")
|
||||||
@Default
|
@Default
|
||||||
@ -43,44 +41,19 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
|
|||||||
@Default
|
@Default
|
||||||
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
|
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
|
||||||
|
|
||||||
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> otherFunctions, Map<String, FunctionTemplate> samplers) {
|
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers, Map<String, FunctionTemplate> globalFunctions) {
|
||||||
this.otherFunctions = otherFunctions;
|
this.globalSamplers = globalSamplers;
|
||||||
this.globalFunctions = samplers;
|
this.globalFunctions = globalFunctions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NoiseSampler get() {
|
public NoiseSampler get() {
|
||||||
|
var mergedFunctions = new HashMap<>(globalFunctions); mergedFunctions.putAll(functions);
|
||||||
|
var mergedSamplers = new HashMap<>(globalSamplers); mergedSamplers.putAll(samplers);
|
||||||
try {
|
try {
|
||||||
Map<String, Function> noiseFunctionMap = generateFunctions();
|
return new ExpressionFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars);
|
||||||
return new ExpressionFunction(noiseFunctionMap, expression, vars);
|
|
||||||
} catch(ParseException e) {
|
} catch(ParseException e) {
|
||||||
throw new RuntimeException("Failed to parse expression.", e);
|
throw new RuntimeException("Failed to parse expression.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, Function> generateFunctions() throws ParseException {
|
|
||||||
Map<String, Function> noiseFunctionMap = new HashMap<>();
|
|
||||||
|
|
||||||
for(Map.Entry<String, FunctionTemplate> entry : globalFunctions.entrySet()) {
|
|
||||||
noiseFunctionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) {
|
|
||||||
noiseFunctionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
otherFunctions.forEach((id, function) -> {
|
|
||||||
if(function.getDimensions() == 2) {
|
|
||||||
noiseFunctionMap.put(id, new NoiseFunction2(function.getSampler()));
|
|
||||||
} else noiseFunctionMap.put(id, new NoiseFunction3(function.getSampler()));
|
|
||||||
});
|
|
||||||
|
|
||||||
samplers.forEach((id, function) -> {
|
|
||||||
if(function.getDimensions() == 2) {
|
|
||||||
noiseFunctionMap.put(id, new NoiseFunction2(function.getSampler()));
|
|
||||||
} else noiseFunctionMap.put(id, new NoiseFunction3(function.getSampler()));
|
|
||||||
});
|
|
||||||
|
|
||||||
return noiseFunctionMap;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2020-2021 Polyhedral Development
|
||||||
|
*
|
||||||
|
* The Terra Core Addons are licensed under the terms of the MIT License. For more details,
|
||||||
|
* reference the LICENSE file in this module's root directory.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.dfsek.terra.addons.noise.config.templates.normalizer;
|
||||||
|
|
||||||
|
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Default;
|
||||||
|
import com.dfsek.tectonic.api.config.template.annotations.Value;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
|
||||||
|
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
||||||
|
import com.dfsek.terra.addons.noise.normalizer.ExpressionNormalizer;
|
||||||
|
import com.dfsek.terra.api.config.meta.Meta;
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static com.dfsek.terra.addons.noise.paralithic.FunctionUtil.convertFunctionsAndSamplers;
|
||||||
|
|
||||||
|
|
||||||
|
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
|
||||||
|
public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionNormalizer> {
|
||||||
|
|
||||||
|
private final Map<String, DimensionApplicableNoiseSampler> globalSamplers;
|
||||||
|
private final Map<String, FunctionTemplate> globalFunctions;
|
||||||
|
|
||||||
|
@Value("expression")
|
||||||
|
private @Meta String expression;
|
||||||
|
|
||||||
|
@Value("variables")
|
||||||
|
@Default
|
||||||
|
private @Meta Map<String, @Meta Double> vars = new HashMap<>();
|
||||||
|
|
||||||
|
@Value("samplers")
|
||||||
|
@Default
|
||||||
|
private @Meta LinkedHashMap<String, @Meta DimensionApplicableNoiseSampler> samplers = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
@Value("functions")
|
||||||
|
@Default
|
||||||
|
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
public ExpressionNormalizerTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers, Map<String, FunctionTemplate> globalFunctions) {
|
||||||
|
this.globalSamplers = globalSamplers;
|
||||||
|
this.globalFunctions = globalFunctions;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NoiseSampler get() {
|
||||||
|
var mergedFunctions = new HashMap<>(globalFunctions); mergedFunctions.putAll(functions);
|
||||||
|
var mergedSamplers = new HashMap<>(globalSamplers); mergedSamplers.putAll(samplers);
|
||||||
|
try {
|
||||||
|
return new ExpressionNormalizer(function, convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars);
|
||||||
|
} catch(ParseException e) {
|
||||||
|
throw new RuntimeException("Failed to parse expression.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package com.dfsek.terra.addons.noise.normalizer;
|
||||||
|
|
||||||
|
import com.dfsek.paralithic.Expression;
|
||||||
|
import com.dfsek.paralithic.eval.parser.Parser;
|
||||||
|
import com.dfsek.paralithic.eval.parser.Scope;
|
||||||
|
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||||
|
import com.dfsek.paralithic.functions.Function;
|
||||||
|
|
||||||
|
import com.dfsek.terra.api.noise.NoiseSampler;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
public class ExpressionNormalizer extends Normalizer {
|
||||||
|
|
||||||
|
private final Expression expression;
|
||||||
|
|
||||||
|
public ExpressionNormalizer(NoiseSampler sampler, Map<String, Function> functions, String eq, Map<String, Double> vars)
|
||||||
|
throws ParseException {
|
||||||
|
super(sampler);
|
||||||
|
Parser p = new Parser();
|
||||||
|
Scope scope = new Scope();
|
||||||
|
scope.addInvocationVariable("in");
|
||||||
|
vars.forEach(scope::create);
|
||||||
|
functions.forEach(p::registerFunction);
|
||||||
|
expression = p.parse(eq, scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double normalize(double in) {
|
||||||
|
return expression.evaluate(in);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.dfsek.terra.addons.noise.paralithic;
|
||||||
|
|
||||||
|
import com.dfsek.paralithic.eval.tokenizer.ParseException;
|
||||||
|
import com.dfsek.paralithic.functions.Function;
|
||||||
|
|
||||||
|
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
|
||||||
|
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
|
||||||
|
import com.dfsek.terra.addons.noise.paralithic.defined.UserDefinedFunction;
|
||||||
|
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2;
|
||||||
|
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
public class FunctionUtil {
|
||||||
|
private FunctionUtil() {}
|
||||||
|
|
||||||
|
public static Map<String, Function> convertFunctionsAndSamplers(Map<String, FunctionTemplate> functions,
|
||||||
|
Map<String, DimensionApplicableNoiseSampler> samplers) throws ParseException {
|
||||||
|
Map<String, Function> functionMap = new HashMap<>();
|
||||||
|
for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) {
|
||||||
|
functionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue()));
|
||||||
|
}
|
||||||
|
samplers.forEach((id, sampler) -> functionMap.put(id,
|
||||||
|
sampler.getDimensions() == 2 ?
|
||||||
|
new NoiseFunction2(sampler.getSampler()) :
|
||||||
|
new NoiseFunction3(sampler.getSampler())));
|
||||||
|
return functionMap;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user