diff --git a/common/src/main/java/com/dfsek/terra/api/math/noise/normalizer/ExpressionNormalizer.java b/common/src/main/java/com/dfsek/terra/api/math/noise/normalizer/ExpressionNormalizer.java deleted file mode 100644 index a5d603abf..000000000 --- a/common/src/main/java/com/dfsek/terra/api/math/noise/normalizer/ExpressionNormalizer.java +++ /dev/null @@ -1,33 +0,0 @@ -package com.dfsek.terra.api.math.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.terra.api.math.noise.NoiseSampler; -import com.dfsek.terra.api.math.parsii.noise.NoiseFunction2; -import com.dfsek.terra.api.math.parsii.noise.NoiseFunction3; - -import java.util.Map; - -public class ExpressionNormalizer extends Normalizer { - private final Expression expression; - - public ExpressionNormalizer(NoiseSampler sampler, String eq, Map vars) throws ParseException { - super(sampler); - Parser p = new Parser(); - Scope scope = new Scope(); - scope.addInvocationVariable("in"); - - vars.forEach(scope::create); - - p.registerFunction("super2", new NoiseFunction2(sampler)); - p.registerFunction("super3", new NoiseFunction3(sampler)); - expression = p.parse(eq); - } - - @Override - public double normalize(double in) { - return expression.evaluate(in); - } -} diff --git a/common/src/main/java/com/dfsek/terra/api/math/noise/samplers/noise/ExpressionFunction.java b/common/src/main/java/com/dfsek/terra/api/math/noise/samplers/noise/ExpressionFunction.java new file mode 100644 index 000000000..90b22f413 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/api/math/noise/samplers/noise/ExpressionFunction.java @@ -0,0 +1,39 @@ +package com.dfsek.terra.api.math.noise.samplers.noise; + +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 java.util.Map; + +public class ExpressionFunction extends NoiseFunction { + private final Expression expression; + + public ExpressionFunction(Map functions, String eq, Map vars) throws ParseException { + super(0); + Parser p = new Parser(); + Scope scope = new Scope(); + + scope.addInvocationVariable("x"); + scope.addInvocationVariable("y"); + scope.addInvocationVariable("z"); + + vars.forEach(scope::create); + + functions.forEach(p::registerFunction); + + expression = p.parse(eq, scope); + } + + @Override + public double getNoiseRaw(int seed, double x, double y) { + return expression.evaluate(x, 0, y); + } + + @Override + public double getNoiseRaw(int seed, double x, double y, double z) { + return expression.evaluate(x, y, z); + } +} diff --git a/common/src/main/java/com/dfsek/terra/api/math/noise/samplers/noise/NoiseFunction.java b/common/src/main/java/com/dfsek/terra/api/math/noise/samplers/noise/NoiseFunction.java index 6f7c41311..6c5829f44 100644 --- a/common/src/main/java/com/dfsek/terra/api/math/noise/samplers/noise/NoiseFunction.java +++ b/common/src/main/java/com/dfsek/terra/api/math/noise/samplers/noise/NoiseFunction.java @@ -12,7 +12,7 @@ public abstract class NoiseFunction implements NoiseSampler { protected double frequency = 0.02d; - protected int seed = 2403; + protected int seed; public NoiseFunction(int seed) { this.seed = seed; diff --git a/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/ExpressionFunctionTemplate.java b/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/ExpressionFunctionTemplate.java new file mode 100644 index 000000000..18264a7b0 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/ExpressionFunctionTemplate.java @@ -0,0 +1,68 @@ +package com.dfsek.terra.config.loaders.config.sampler.templates.noise; + +import com.dfsek.paralithic.eval.tokenizer.ParseException; +import com.dfsek.paralithic.functions.Function; +import com.dfsek.tectonic.annotations.Default; +import com.dfsek.tectonic.annotations.Value; +import com.dfsek.tectonic.config.ValidatedConfigTemplate; +import com.dfsek.tectonic.exception.ValidationException; +import com.dfsek.terra.api.math.noise.NoiseSampler; +import com.dfsek.terra.api.math.noise.samplers.noise.ExpressionFunction; +import com.dfsek.terra.api.math.parsii.BlankFunction; +import com.dfsek.terra.api.math.parsii.noise.NoiseFunction2; +import com.dfsek.terra.api.math.parsii.noise.NoiseFunction3; +import com.dfsek.terra.api.util.seeded.NoiseSeeded; + +import java.util.HashMap; +import java.util.Map; + +@SuppressWarnings({"unused", "FieldMayBeFinal"}) +public class ExpressionFunctionTemplate extends NoiseTemplate implements ValidatedConfigTemplate { + @Value("variables") + @Default + private Map vars = new HashMap<>(); + + @Value("equation") + private String equation; + + @Value("functions") + private Map functions; + + public ExpressionFunctionTemplate() { + frequency = 1; + } + + @Override + public NoiseSampler apply(Long seed) { + try { + Map noiseFunctionMap = new HashMap<>(); + + functions.forEach((id, function) -> { + if(function.getDimensions() == 2) { + noiseFunctionMap.put(id, new NoiseFunction2(function.apply(seed))); + } else noiseFunctionMap.put(id, new NoiseFunction3(function.apply(seed))); + }); + + return new ExpressionFunction(noiseFunctionMap, equation, vars); + } catch(ParseException e) { + throw new IllegalStateException(e); + } + } + + @Override + public boolean validate() throws ValidationException { + try { + Map noiseFunctionMap = new HashMap<>(); + + functions.forEach((id, function) -> { + if(function.getDimensions() == 2) { + noiseFunctionMap.put(id, new BlankFunction(2)); + } else noiseFunctionMap.put(id, new BlankFunction(3)); + }); + new ExpressionFunction(noiseFunctionMap, equation, vars); + } catch(ParseException e) { + throw new ValidationException("Errors occurred while parsing noise equation: ", e); + } + return super.validate(); + } +} diff --git a/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/NoiseTemplate.java b/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/NoiseTemplate.java index dba900856..9fb123865 100644 --- a/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/NoiseTemplate.java +++ b/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/NoiseTemplate.java @@ -5,6 +5,7 @@ import com.dfsek.tectonic.annotations.Value; import com.dfsek.terra.api.math.noise.samplers.noise.NoiseFunction; import com.dfsek.terra.config.loaders.config.sampler.templates.SamplerTemplate; +@SuppressWarnings({"unused", "FieldMayBeFinal"}) public abstract class NoiseTemplate extends SamplerTemplate { @Value("frequency") @Default diff --git a/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/fractal/PingPongTemplate.java b/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/fractal/PingPongTemplate.java index 781db4371..1930ef761 100644 --- a/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/fractal/PingPongTemplate.java +++ b/common/src/main/java/com/dfsek/terra/config/loaders/config/sampler/templates/noise/fractal/PingPongTemplate.java @@ -4,7 +4,7 @@ import com.dfsek.tectonic.annotations.Default; import com.dfsek.tectonic.annotations.Value; import com.dfsek.terra.api.math.noise.NoiseSampler; import com.dfsek.terra.api.math.noise.samplers.noise.fractal.PingPongSampler; - +@SuppressWarnings({"unused", "FieldMayBeFinal"}) public class PingPongTemplate extends FractalTemplate { @Value("ping-pong") @Default diff --git a/common/src/main/java/com/dfsek/terra/registry/config/NoiseRegistry.java b/common/src/main/java/com/dfsek/terra/registry/config/NoiseRegistry.java index af28fbe3e..2a2d317a5 100644 --- a/common/src/main/java/com/dfsek/terra/registry/config/NoiseRegistry.java +++ b/common/src/main/java/com/dfsek/terra/registry/config/NoiseRegistry.java @@ -11,6 +11,7 @@ import com.dfsek.terra.api.util.seeded.NoiseSeeded; import com.dfsek.terra.config.loaders.config.sampler.templates.DomainWarpTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.ImageSamplerTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.noise.CellularNoiseTemplate; +import com.dfsek.terra.config.loaders.config.sampler.templates.noise.ExpressionFunctionTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.noise.SimpleNoiseTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.noise.fractal.BrownianMotionTemplate; import com.dfsek.terra.config.loaders.config.sampler.templates.noise.fractal.PingPongTemplate; @@ -27,6 +28,7 @@ public class NoiseRegistry extends TerraRegistry