WIP Seismic Integration

This commit is contained in:
Zoë Gidiere
2025-03-01 21:32:39 -07:00
parent 8366a5288b
commit 5892464a1d
239 changed files with 623 additions and 6195 deletions
@@ -8,6 +8,9 @@
package com.dfsek.terra.addons.noise;
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
import com.dfsek.seismic.algorithms.sampler.noise.CellularSampler;
import com.dfsek.seismic.type.CubicSpline;
import com.dfsek.seismic.type.DistanceFunction;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import java.util.LinkedHashMap;
@@ -16,13 +19,12 @@ import java.util.function.Supplier;
import com.dfsek.terra.addons.manifest.api.AddonInitializer;
import com.dfsek.terra.addons.noise.config.CubicSplinePointTemplate;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.DimensionApplicableSampler;
import com.dfsek.terra.addons.noise.config.templates.BinaryArithmeticTemplate;
import com.dfsek.terra.addons.noise.config.templates.CacheSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.DerivativeNoiseSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.DerivativeSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.DomainWarpTemplate;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.addons.noise.config.templates.ImageSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.KernelTemplate;
import com.dfsek.terra.addons.noise.config.templates.LinearHeightmapSamplerTemplate;
import com.dfsek.terra.addons.noise.config.templates.TranslateSamplerTemplate;
@@ -45,37 +47,25 @@ import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizer
import com.dfsek.terra.addons.noise.config.templates.normalizer.PosterizationNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.ProbabilityNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.ScaleNormalizerTemplate;
import com.dfsek.terra.addons.noise.math.CubicSpline;
import com.dfsek.terra.addons.noise.samplers.arithmetic.AdditionSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.DivisionSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.MaxSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.MinSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.MultiplicationSampler;
import com.dfsek.terra.addons.noise.samplers.arithmetic.SubtractionSampler;
import com.dfsek.terra.addons.noise.samplers.noise.CellularSampler;
import com.dfsek.terra.addons.noise.samplers.noise.DistanceSampler;
import com.dfsek.terra.addons.noise.samplers.noise.random.GaussianNoiseSampler;
import com.dfsek.terra.addons.noise.samplers.noise.random.PositiveWhiteNoiseSampler;
import com.dfsek.terra.addons.noise.samplers.noise.random.WhiteNoiseSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2SSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.PerlinSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.SimplexSampler;
import com.dfsek.terra.addons.noise.samplers.noise.value.ValueCubicSampler;
import com.dfsek.terra.addons.noise.samplers.noise.value.ValueSampler;
import com.dfsek.terra.api.Platform;
import com.dfsek.terra.api.addon.BaseAddon;
import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent;
import com.dfsek.terra.api.event.functional.FunctionalEventHandler;
import com.dfsek.terra.api.inject.annotations.Inject;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.DerivativeSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.util.reflection.TypeKey;
import com.dfsek.seismic.algorithms.sampler.noise.*;
import com.dfsek.seismic.algorithms.sampler.noise.simplex.*;
import com.dfsek.seismic.algorithms.sampler.noise.fractal.*;
import com.dfsek.seismic.algorithms.sampler.noise.random.*;
import com.dfsek.seismic.algorithms.sampler.noise.value.*;
import com.dfsek.seismic.algorithms.sampler.normalizer.*;
import com.dfsek.seismic.algorithms.sampler.arithmetic.*;
public class NoiseAddon implements AddonInitializer {
public static final TypeKey<Supplier<ObjectTemplate<NoiseSampler>>> NOISE_SAMPLER_TOKEN = new TypeKey<>() {
public static final TypeKey<Supplier<ObjectTemplate<Sampler>>> NOISE_SAMPLER_TOKEN = new TypeKey<>() {
};
@Inject
private Platform plugin;
@@ -91,19 +81,19 @@ public class NoiseAddon implements AddonInitializer {
.then(event -> {
ParseOptions expressionParseOptions = event.getPack().getExpressionParseOptions();
CheckedRegistry<Supplier<ObjectTemplate<NoiseSampler>>> noiseRegistry = event.getPack().getOrCreateRegistry(
CheckedRegistry<Supplier<ObjectTemplate<Sampler>>> noiseRegistry = event.getPack().getOrCreateRegistry(
NOISE_SAMPLER_TOKEN);
event.getPack()
.applyLoader(CellularSampler.DistanceFunction.class,
(type, o, loader, depthTracker) -> CellularSampler.DistanceFunction.valueOf((String) o))
.applyLoader(DistanceFunction.class,
(type, o, loader, depthTracker) -> DistanceFunction.valueOf((String) o))
.applyLoader(CellularSampler.ReturnType.class,
(type, o, loader, depthTracker) -> CellularSampler.ReturnType.valueOf((String) o))
.applyLoader(DistanceSampler.DistanceFunction.class,
(type, o, loader, depthTracker) -> DistanceSampler.DistanceFunction.valueOf((String) o))
.applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::new)
.applyLoader(DistanceFunction.class,
(type, o, loader, depthTracker) -> DistanceFunction.valueOf((String) o))
.applyLoader(DimensionApplicableSampler.class, DimensionApplicableSampler::new)
.applyLoader(FunctionTemplate.class, () -> new FunctionTemplate(expressionParseOptions))
.applyLoader(CubicSpline.Point.class, CubicSplinePointTemplate::new)
.applyLoader(DerivativeNoiseSampler.class, DerivativeNoiseSamplerTemplate::new);
.applyLoader(DerivativeSampler.class, DerivativeSamplerTemplate::new);
noiseRegistry.register(addon.key("LINEAR"), LinearNormalizerTemplate::new);
noiseRegistry.register(addon.key("LINEAR_MAP"), LinearMapNormalizerTemplate::new);
@@ -114,8 +104,6 @@ public class NoiseAddon implements AddonInitializer {
noiseRegistry.register(addon.key("POSTERIZATION"), PosterizationNormalizerTemplate::new);
noiseRegistry.register(addon.key("CUBIC_SPLINE"), CubicSplineNormalizerTemplate::new);
noiseRegistry.register(addon.key("IMAGE"), ImageSamplerTemplate::new);
noiseRegistry.register(addon.key("DOMAIN_WARP"), DomainWarpTemplate::new);
noiseRegistry.register(addon.key("FBM"), BrownianMotionTemplate::new);
@@ -157,7 +145,7 @@ public class NoiseAddon implements AddonInitializer {
noiseRegistry.register(addon.key("CACHE"), CacheSamplerTemplate::new);
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
Map<String, DimensionApplicableSampler> packSamplers = new LinkedHashMap<>();
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
noiseRegistry.register(addon.key("EXPRESSION"), () -> new ExpressionFunctionTemplate(packSamplers, packFunctions, expressionParseOptions));
noiseRegistry.register(addon.key("EXPRESSION_NORMALIZER"),
@@ -14,7 +14,7 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.LinkedHashMap;
import java.util.Map;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.DimensionApplicableSampler;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.properties.Properties;
@@ -24,13 +24,13 @@ import com.dfsek.terra.api.properties.Properties;
public class NoiseConfigPackTemplate implements ConfigTemplate, Properties {
@Value("samplers")
@Default
private @Meta Map<String, @Meta DimensionApplicableNoiseSampler> noiseBuilderMap = new LinkedHashMap<>();
private @Meta Map<String, @Meta DimensionApplicableSampler> noiseBuilderMap = new LinkedHashMap<>();
@Value("functions")
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> expressions = new LinkedHashMap<>();
public Map<String, DimensionApplicableNoiseSampler> getSamplers() {
public Map<String, DimensionApplicableSampler> getSamplers() {
return noiseBuilderMap;
}
@@ -1,11 +1,11 @@
package com.dfsek.terra.addons.noise.config;
import com.dfsek.seismic.type.CubicSpline.Point;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.addons.noise.math.CubicSpline.Point;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.config.meta.Meta;
public class CubicSplinePointTemplate implements ObjectTemplate<Point> {
@@ -11,18 +11,18 @@ import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public class DimensionApplicableNoiseSampler implements ObjectTemplate<DimensionApplicableNoiseSampler> {
public class DimensionApplicableSampler implements ObjectTemplate<DimensionApplicableSampler> {
@Value("dimensions")
private @Meta int dimensions;
@Value(".")
private @Meta NoiseSampler sampler;
private @Meta Sampler sampler;
@Override
public DimensionApplicableNoiseSampler get() {
public DimensionApplicableSampler get() {
return this;
}
@@ -30,7 +30,7 @@ public class DimensionApplicableNoiseSampler implements ObjectTemplate<Dimension
return dimensions;
}
public NoiseSampler getSampler() {
public Sampler getSampler() {
return sampler;
}
}
@@ -1,6 +1,6 @@
package com.dfsek.terra.addons.noise.samplers;
package com.dfsek.terra.addons.noise.config.sampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.api.util.cache.DoubleSeededVector2Key;
import com.dfsek.terra.api.util.cache.DoubleSeededVector3Key;
@@ -17,13 +17,13 @@ import static com.dfsek.terra.api.util.cache.CacheUtils.CACHE_EXECUTOR;
@Experimental
public class CacheSampler implements NoiseSampler {
public class CacheSampler implements Sampler {
private final NoiseSampler sampler;
private final Sampler sampler;
private final ThreadLocal<Mutable<DoubleSeededVector2Key, LoadingCache<DoubleSeededVector2Key, Double>>> cache2D;
private final ThreadLocal<Mutable<DoubleSeededVector3Key, LoadingCache<DoubleSeededVector3Key, Double>>> cache3D;
public CacheSampler(NoiseSampler sampler, int dimensions) {
public CacheSampler(Sampler sampler, int dimensions) {
this.sampler = sampler;
if (dimensions == 2) {
this.cache2D = ThreadLocal.withInitial(() -> {
@@ -54,16 +54,16 @@ public class CacheSampler implements NoiseSampler {
private Double sampleNoise(DoubleSeededVector2Key vec) {
this.cache2D.get().setLeft(new DoubleSeededVector2Key(0, 0, 0));
return this.sampler.noise(vec.seed, vec.x, vec.z);
return this.sampler.getSample(vec.seed, vec.x, vec.z);
}
private Double sampleNoise(DoubleSeededVector3Key vec) {
this.cache3D.get().setLeft(new DoubleSeededVector3Key(0, 0, 0, 0));
return this.sampler.noise(vec.seed, vec.x, vec.y, vec.z);
return this.sampler.getSample(vec.seed, vec.x, vec.y, vec.z);
}
@Override
public double noise(long seed, double x, double y) {
public double getSample(long seed, double x, double y) {
Mutable<DoubleSeededVector2Key, LoadingCache<DoubleSeededVector2Key, Double>> cachePair = cache2D.get();
DoubleSeededVector2Key mutableKey = cachePair.getLeft();
mutableKey.set(x, y, seed);
@@ -71,7 +71,7 @@ public class CacheSampler implements NoiseSampler {
}
@Override
public double noise(long seed, double x, double y, double z) {
public double getSample(long seed, double x, double y, double z) {
Mutable<DoubleSeededVector3Key, LoadingCache<DoubleSeededVector3Key, Double>> cachePair = cache3D.get();
DoubleSeededVector3Key mutableKey = cachePair.getLeft();
mutableKey.set(x, y, z, seed);
@@ -1,22 +1,22 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.arithmetic.BinaryArithmeticSampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.function.BiFunction;
import com.dfsek.terra.addons.noise.samplers.arithmetic.BinaryArithmeticSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public class BinaryArithmeticTemplate<T extends BinaryArithmeticSampler> extends SamplerTemplate<T> {
private final BiFunction<NoiseSampler, NoiseSampler, T> function;
private final BiFunction<Sampler, Sampler, T> function;
@Value("left")
private @Meta NoiseSampler left;
private @Meta Sampler left;
@Value("right")
private @Meta NoiseSampler right;
private @Meta Sampler right;
public BinaryArithmeticTemplate(BiFunction<NoiseSampler, NoiseSampler, T> function) {
public BinaryArithmeticTemplate(BiFunction<Sampler, Sampler, T> function) {
this.function = function;
}
@@ -3,9 +3,9 @@ package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.CacheSampler;
import com.dfsek.terra.addons.noise.samplers.LinearHeightmapSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.terra.addons.noise.config.sampler.CacheSampler;
import org.jetbrains.annotations.ApiStatus.Experimental;
@@ -14,14 +14,14 @@ import org.jetbrains.annotations.ApiStatus.Experimental;
public class CacheSamplerTemplate extends SamplerTemplate<CacheSampler> {
@Value("sampler")
@Default
private NoiseSampler sampler;
private Sampler sampler;
public CacheSamplerTemplate() {
}
@Override
public NoiseSampler get() {
public Sampler get() {
return new CacheSampler(sampler, getDimensions());
}
}
@@ -1,26 +0,0 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.exception.ValidationException;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
public class DerivativeNoiseSamplerTemplate extends SamplerTemplate<DerivativeNoiseSampler> {
@Value(".")
private NoiseSampler sampler;
@Override
public boolean validate() throws ValidationException {
if(!DerivativeNoiseSampler.isDifferentiable(sampler)) throw new ValidationException(
"Provided sampler does not support calculating a derivative");
return super.validate();
}
@Override
public DerivativeNoiseSampler get() {
return (DerivativeNoiseSampler) sampler;
}
}
@@ -0,0 +1,26 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.type.sampler.DerivativeSampler;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.exception.ValidationException;
import com.dfsek.seismic.type.sampler.Sampler;
public class DerivativeSamplerTemplate extends SamplerTemplate<DerivativeSampler> {
@Value(".")
private Sampler sampler;
@Override
public boolean validate() throws ValidationException {
if(!DerivativeSampler.isDifferentiable(sampler)) throw new ValidationException(
"Provided sampler does not support calculating a derivative");
return super.validate();
}
@Override
public DerivativeSampler get() {
return (DerivativeSampler) sampler;
}
}
@@ -7,28 +7,28 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.DomainWarpedSampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.DomainWarpedSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class DomainWarpTemplate extends SamplerTemplate<DomainWarpedSampler> {
@Value("warp")
private @Meta NoiseSampler warp;
private @Meta Sampler warp;
@Value("sampler")
private @Meta NoiseSampler function;
private @Meta Sampler function;
@Value("amplitude")
@Default
private @Meta double amplitude = 1;
@Override
public NoiseSampler get() {
public Sampler get() {
return new DomainWarpedSampler(function, warp, amplitude);
}
}
@@ -1,47 +0,0 @@
/*
* Copyright (c) 2020-2025 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;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.image.BufferedImage;
import com.dfsek.terra.addons.noise.samplers.ImageSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class ImageSamplerTemplate extends SamplerTemplate<ImageSampler> {
private static final Logger logger = LoggerFactory.getLogger(ImageSamplerTemplate.class);
private static boolean used = false;
@Value("image")
private @Meta BufferedImage image;
@Value("frequency")
private @Meta double frequency;
@Value("channel")
private ImageSampler.@Meta Channel channel;
@Override
public NoiseSampler get() {
if(!used) {
logger.warn("The IMAGE NoiseSampler implemented by the config-noise-function addon is deprecated. " +
"It is recommended to use the IMAGE NoiseSampler implemented by the config-noise-image " +
"addon instead.");
used = true;
}
return new ImageSampler(image, channel, frequency);
}
}
@@ -7,15 +7,15 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.KernelSampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.tectonic.api.exception.ValidationException;
import java.util.List;
import com.dfsek.terra.addons.noise.samplers.KernelSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
@@ -29,14 +29,14 @@ public class KernelTemplate extends SamplerTemplate<KernelSampler> {
private @Meta double factor = 1;
@Value("sampler")
private @Meta NoiseSampler function;
private @Meta Sampler function;
@Value("frequency")
@Default
private @Meta double frequency = 1;
@Override
public NoiseSampler get() {
public Sampler get() {
double[][] k = new double[kernel.size()][kernel.get(0).size()];
for(int x = 0; x < kernel.size(); x++) {
@@ -1,18 +1,18 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.LinearHeightmapSampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.LinearHeightmapSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings("FieldMayBeFinal")
public class LinearHeightmapSamplerTemplate extends SamplerTemplate<LinearHeightmapSampler> {
@Value("sampler")
@Default
private @Meta NoiseSampler sampler = NoiseSampler.zero();
private @Meta Sampler sampler = Sampler.zero();
@Value("base")
private @Meta double base;
@@ -22,7 +22,7 @@ public class LinearHeightmapSamplerTemplate extends SamplerTemplate<LinearHeight
private @Meta double scale = 1;
@Override
public NoiseSampler get() {
public Sampler get() {
return new LinearHeightmapSampler(sampler, scale, base);
}
}
@@ -14,11 +14,11 @@ import com.dfsek.tectonic.api.config.template.object.ObjectTemplate;
import com.dfsek.tectonic.api.exception.ValidationException;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings("FieldMayBeFinal")
public abstract class SamplerTemplate<T extends NoiseSampler> implements ValidatedConfigTemplate, ObjectTemplate<NoiseSampler> {
public abstract class SamplerTemplate<T extends Sampler> implements ValidatedConfigTemplate, ObjectTemplate<Sampler> {
@Value("dimensions")
@Default
private @Meta int dimensions = 2;
@@ -1,17 +1,17 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.seismic.algorithms.sampler.TranslateSampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.TranslateSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public class TranslateSamplerTemplate extends SamplerTemplate<TranslateSampler> {
@Value("sampler")
private NoiseSampler sampler;
private Sampler sampler;
@Value("x")
@Default
@@ -26,7 +26,7 @@ public class TranslateSamplerTemplate extends SamplerTemplate<TranslateSampler>
private @Meta double z = 0;
@Override
public NoiseSampler get() {
public Sampler get() {
return new TranslateSampler(sampler, x, y, z);
}
}
@@ -7,20 +7,22 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.CellularSampler;
import com.dfsek.seismic.algorithms.sampler.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.seismic.type.DistanceFunction;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.noise.CellularSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings("FieldMayBeFinal")
public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
@Value("distance")
@Default
private CellularSampler.@Meta DistanceFunction cellularDistanceFunction = CellularSampler.DistanceFunction.EuclideanSq;
private @Meta DistanceFunction cellularDistanceFunction = DistanceFunction.EuclideanSq;
@Value("return")
@Default
@@ -33,14 +35,14 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
@Value("lookup")
@Default
private @Meta NoiseSampler lookup = new OpenSimplex2Sampler();
private @Meta Sampler lookup = new OpenSimplex2Sampler();
@Value("salt-lookup")
@Default
private @Meta boolean saltLookup = true;
@Override
public NoiseSampler get() {
public Sampler get() {
CellularSampler sampler = new CellularSampler();
sampler.setNoiseLookup(lookup);
sampler.setFrequency(frequency);
@@ -7,13 +7,13 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.ConstantSampler;
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.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.ConstantSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings("FieldMayBeFinal")
@@ -23,7 +23,7 @@ public class ConstantNoiseTemplate extends SamplerTemplate<ConstantSampler> {
private @Meta double value = 0d;
@Override
public NoiseSampler get() {
public Sampler get() {
return new ConstantSampler(value);
}
}
@@ -1,8 +0,0 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
public abstract class DerivativeNoiseTemplate<T extends DerivativeNoiseFunction> extends NoiseTemplate<T> {
}
@@ -1,11 +1,12 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.DistanceSampler;
import com.dfsek.seismic.type.DistanceFunction;
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.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.DistanceSampler;
import com.dfsek.terra.addons.noise.samplers.noise.DistanceSampler.DistanceFunction;
import com.dfsek.terra.api.config.meta.Meta;
@@ -13,7 +14,7 @@ public class DistanceSamplerTemplate extends SamplerTemplate<DistanceSampler> {
@Value("distance-function")
@Default
private DistanceSampler.@Meta DistanceFunction distanceFunction = DistanceFunction.Euclidean;
private @Meta DistanceFunction distanceFunction = DistanceFunction.Euclidean;
@Value("point.x")
@Default
@@ -9,6 +9,7 @@ package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.sampler.noise.ExpressionNoiseFunction;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
@@ -16,19 +17,18 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.DimensionApplicableSampler;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.ExpressionFunction;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
import static com.dfsek.terra.addons.noise.paralithic.FunctionUtil.convertFunctionsAndSamplers;
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFunction> {
private final Map<String, DimensionApplicableNoiseSampler> globalSamplers;
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionNoiseFunction> {
private final Map<String, DimensionApplicableSampler> globalSamplers;
private final Map<String, FunctionTemplate> globalFunctions;
private final ParseOptions parseOptions;
@Value("variables")
@@ -38,12 +38,12 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
private @Meta String expression;
@Value("samplers")
@Default
private @Meta LinkedHashMap<String, @Meta DimensionApplicableNoiseSampler> samplers = new LinkedHashMap<>();
private @Meta LinkedHashMap<String, @Meta DimensionApplicableSampler> samplers = new LinkedHashMap<>();
@Value("functions")
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers,
public ExpressionFunctionTemplate(Map<String, DimensionApplicableSampler> globalSamplers,
Map<String, FunctionTemplate> globalFunctions,
ParseOptions parseOptions) {
this.globalSamplers = globalSamplers;
@@ -52,13 +52,13 @@ public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFuncti
}
@Override
public NoiseSampler get() {
public Sampler get() {
var mergedFunctions = new HashMap<>(globalFunctions);
mergedFunctions.putAll(functions);
var mergedSamplers = new HashMap<>(globalSamplers);
mergedSamplers.putAll(samplers);
try {
return new ExpressionFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars, parseOptions);
return new ExpressionNoiseFunction(convertFunctionsAndSamplers(mergedFunctions, mergedSamplers), expression, vars, parseOptions);
} catch(ParseException e) {
throw new RuntimeException("Failed to parse expression.", e);
}
@@ -7,16 +7,17 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.GaborSampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.noise.GaborNoiseSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings("FieldMayBeFinal")
public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
public class GaborNoiseTemplate extends NoiseTemplate<GaborSampler> {
@Value("rotation")
@Default
private @Meta double rotation = 0.25;
@@ -38,15 +39,15 @@ public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
private @Meta double f0 = 0.625;
@Override
public NoiseSampler get() {
GaborNoiseSampler gaborNoiseSampler = new GaborNoiseSampler();
gaborNoiseSampler.setFrequency(frequency);
gaborNoiseSampler.setRotation(rotation);
gaborNoiseSampler.setIsotropic(isotropic);
gaborNoiseSampler.setDeviation(deviation);
gaborNoiseSampler.setImpulsesPerKernel(impulses);
gaborNoiseSampler.setFrequency0(f0);
gaborNoiseSampler.setSalt(salt);
return gaborNoiseSampler;
public Sampler get() {
GaborSampler gaborSampler = new GaborSampler();
gaborSampler.setFrequency(frequency);
gaborSampler.setRotation(rotation);
gaborSampler.setIsotropic(isotropic);
gaborSampler.setDeviation(deviation);
gaborSampler.setImpulsesPerKernel(impulses);
gaborSampler.setFrequency0(f0);
gaborSampler.setSalt(salt);
return gaborSampler;
}
}
@@ -7,11 +7,11 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.NoiseFunction;
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.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
import com.dfsek.terra.api.config.meta.Meta;
@@ -1,12 +1,12 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.seismic.algorithms.sampler.noise.PseudoErosionSampler;
import com.dfsek.seismic.algorithms.sampler.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.noise.PseudoErosionSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
import com.dfsek.seismic.type.sampler.DerivativeSampler;
public class PseudoErosionTemplate extends NoiseTemplate<PseudoErosionSampler> {
@@ -45,7 +45,7 @@ public class PseudoErosionTemplate extends NoiseTemplate<PseudoErosionSampler> {
@Value("sampler")
@Default
private DerivativeNoiseSampler heightSampler = new OpenSimplex2Sampler();
private DerivativeSampler heightSampler = new OpenSimplex2Sampler();
@Value("slope-mask.enable")
@Default
@@ -9,8 +9,8 @@ package com.dfsek.terra.addons.noise.config.templates.noise;
import java.util.function.Supplier;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.algorithms.sampler.noise.NoiseFunction;
import com.dfsek.seismic.type.sampler.Sampler;
public class SimpleNoiseTemplate extends NoiseTemplate<NoiseFunction> {
@@ -21,7 +21,7 @@ public class SimpleNoiseTemplate extends NoiseTemplate<NoiseFunction> {
}
@Override
public NoiseSampler get() {
public Sampler get() {
NoiseFunction sampler = samplerSupplier.get();
sampler.setFrequency(frequency);
sampler.setSalt(salt);
@@ -7,13 +7,14 @@
package com.dfsek.terra.addons.noise.config.templates.noise.fractal;
import com.dfsek.terra.addons.noise.samplers.noise.fractal.BrownianMotionSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.algorithms.sampler.noise.fractal.BrownianMotionSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public class BrownianMotionTemplate extends FractalTemplate<BrownianMotionSampler> {
@Override
public NoiseSampler get() {
public Sampler get() {
BrownianMotionSampler sampler = new BrownianMotionSampler(function);
sampler.setGain(fractalGain);
sampler.setLacunarity(fractalLacunarity);
@@ -7,13 +7,13 @@
package com.dfsek.terra.addons.noise.config.templates.noise.fractal;
import com.dfsek.seismic.algorithms.sampler.noise.fractal.FractalNoiseFunction;
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.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.fractal.FractalNoiseFunction;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public abstract class FractalTemplate<T extends FractalNoiseFunction> extends SamplerTemplate<T> {
@@ -34,5 +34,5 @@ public abstract class FractalTemplate<T extends FractalNoiseFunction> extends Sa
protected @Meta double weightedStrength = 0.0D;
@Value("sampler")
protected @Meta NoiseSampler function;
protected @Meta Sampler function;
}
@@ -7,12 +7,12 @@
package com.dfsek.terra.addons.noise.config.templates.noise.fractal;
import com.dfsek.seismic.algorithms.sampler.noise.fractal.PingPongSampler;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.samplers.noise.fractal.PingPongSampler;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
@@ -22,7 +22,7 @@ public class PingPongTemplate extends FractalTemplate<PingPongSampler> {
private @Meta double pingPong = 2.0D;
@Override
public NoiseSampler get() {
public Sampler get() {
PingPongSampler sampler = new PingPongSampler(function);
sampler.setGain(fractalGain);
sampler.setLacunarity(fractalLacunarity);
@@ -7,13 +7,14 @@
package com.dfsek.terra.addons.noise.config.templates.noise.fractal;
import com.dfsek.terra.addons.noise.samplers.noise.fractal.RidgedFractalSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.algorithms.sampler.noise.fractal.RidgedFractalSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public class RidgedFractalTemplate extends FractalTemplate<RidgedFractalSampler> {
@Override
public NoiseSampler get() {
public Sampler get() {
RidgedFractalSampler sampler = new RidgedFractalSampler(function);
sampler.setGain(fractalGain);
sampler.setLacunarity(fractalLacunarity);
@@ -7,11 +7,11 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.seismic.algorithms.sampler.normalizer.ClampNormalizer;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.normalizer.ClampNormalizer;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
@@ -23,7 +23,7 @@ public class ClampNormalizerTemplate extends NormalizerTemplate<ClampNormalizer>
private @Meta double min;
@Override
public NoiseSampler get() {
public Sampler get() {
return new ClampNormalizer(function, min, max);
}
}
@@ -1,23 +1,24 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.seismic.algorithms.sampler.normalizer.CubicSplineNormalizer;
import com.dfsek.seismic.type.CubicSpline;
import com.dfsek.seismic.type.CubicSpline.Point;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import java.util.List;
import com.dfsek.terra.addons.noise.math.CubicSpline;
import com.dfsek.terra.addons.noise.math.CubicSpline.Point;
import com.dfsek.terra.addons.noise.normalizer.CubicSplineNoiseSampler;
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public class CubicSplineNormalizerTemplate extends NormalizerTemplate<CubicSplineNoiseSampler> {
public class CubicSplineNormalizerTemplate extends NormalizerTemplate<CubicSplineNormalizer> {
@Value("points")
private @Meta List<@Meta Point> points;
@Override
public NoiseSampler get() {
return new CubicSplineNoiseSampler(function, new CubicSpline(points));
public Sampler get() {
return new CubicSplineNormalizer(function, new CubicSpline(points));
}
}
@@ -16,11 +16,11 @@ import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.DimensionApplicableSampler;
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 com.dfsek.seismic.type.sampler.Sampler;
import com.dfsek.paralithic.sampler.normalizer.ExpressionNormalizer;
import static com.dfsek.terra.addons.noise.paralithic.FunctionUtil.convertFunctionsAndSamplers;
@@ -28,7 +28,7 @@ import static com.dfsek.terra.addons.noise.paralithic.FunctionUtil.convertFuncti
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionNormalizer> {
private final Map<String, DimensionApplicableNoiseSampler> globalSamplers;
private final Map<String, DimensionApplicableSampler> globalSamplers;
private final Map<String, FunctionTemplate> globalFunctions;
private final ParseOptions parseOptions;
@@ -41,13 +41,13 @@ public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionN
@Value("samplers")
@Default
private @Meta LinkedHashMap<String, @Meta DimensionApplicableNoiseSampler> samplers = new LinkedHashMap<>();
private @Meta LinkedHashMap<String, @Meta DimensionApplicableSampler> samplers = new LinkedHashMap<>();
@Value("functions")
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
public ExpressionNormalizerTemplate(Map<String, DimensionApplicableNoiseSampler> globalSamplers,
public ExpressionNormalizerTemplate(Map<String, DimensionApplicableSampler> globalSamplers,
Map<String, FunctionTemplate> globalFunctions,
ParseOptions parseOptions) {
this.globalSamplers = globalSamplers;
@@ -56,7 +56,7 @@ public class ExpressionNormalizerTemplate extends NormalizerTemplate<ExpressionN
}
@Override
public NoiseSampler get() {
public Sampler get() {
var mergedFunctions = new HashMap<>(globalFunctions);
mergedFunctions.putAll(functions);
var mergedSamplers = new HashMap<>(globalSamplers);
@@ -1,11 +1,11 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.seismic.algorithms.sampler.normalizer.LinearMapNormalizer;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.normalizer.LinearMapNormalizer;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public class LinearMapNormalizerTemplate extends NormalizerTemplate<LinearMapNormalizer> {
@@ -25,7 +25,7 @@ public class LinearMapNormalizerTemplate extends NormalizerTemplate<LinearMapNor
private @Meta double bTo;
@Override
public NoiseSampler get() {
public Sampler get() {
return new LinearMapNormalizer(function, aFrom, aTo, bFrom, bTo);
}
}
@@ -7,11 +7,11 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.seismic.algorithms.sampler.normalizer.LinearNormalizer;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.normalizer.LinearNormalizer;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
@@ -23,7 +23,7 @@ public class LinearNormalizerTemplate extends NormalizerTemplate<LinearNormalize
private @Meta double min;
@Override
public NoiseSampler get() {
public Sampler get() {
return new LinearNormalizer(function, min, max);
}
}
@@ -7,12 +7,12 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.seismic.algorithms.sampler.normalizer.NormalNormalizer;
import com.dfsek.tectonic.api.config.template.annotations.Default;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.normalizer.NormalNormalizer;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
@@ -28,7 +28,7 @@ public class NormalNormalizerTemplate extends NormalizerTemplate<NormalNormalize
private @Meta int groups = 16384;
@Override
public NoiseSampler get() {
public Sampler get() {
return new NormalNormalizer(function, groups, mean, stdDev);
}
}
@@ -7,15 +7,15 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.seismic.algorithms.sampler.normalizer.Normalizer;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.normalizer.Normalizer;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public abstract class NormalizerTemplate<T extends Normalizer> extends SamplerTemplate<T> {
@Value("sampler")
protected @Meta NoiseSampler function;
protected @Meta Sampler function;
}
@@ -7,11 +7,11 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.seismic.algorithms.sampler.normalizer.PosterizationNormalizer;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.normalizer.PosterizationNormalizer;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
@@ -20,7 +20,7 @@ public class PosterizationNormalizerTemplate extends NormalizerTemplate<Posteriz
private @Meta int steps;
@Override
public NoiseSampler get() {
public Sampler get() {
return new PosterizationNormalizer(function, steps);
}
}
@@ -1,12 +1,12 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.terra.addons.noise.normalizer.ProbabilityNormalizer;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.algorithms.sampler.normalizer.ProbabilityNormalizer;
import com.dfsek.seismic.type.sampler.Sampler;
public class ProbabilityNormalizerTemplate extends NormalizerTemplate<ProbabilityNormalizer> {
@Override
public NoiseSampler get() {
public Sampler get() {
return new ProbabilityNormalizer(function);
}
}
@@ -1,10 +1,10 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.seismic.algorithms.sampler.normalizer.ScaleNormalizer;
import com.dfsek.tectonic.api.config.template.annotations.Value;
import com.dfsek.terra.addons.noise.normalizer.ScaleNormalizer;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.seismic.type.sampler.Sampler;
public class ScaleNormalizerTemplate extends NormalizerTemplate<ScaleNormalizer> {
@@ -12,7 +12,7 @@ public class ScaleNormalizerTemplate extends NormalizerTemplate<ScaleNormalizer>
private @Meta double amplitude;
@Override
public NoiseSampler get() {
public Sampler get() {
return new ScaleNormalizer(function, amplitude);
}
}
@@ -1,89 +0,0 @@
package com.dfsek.terra.addons.noise.math;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
import static com.dfsek.terra.api.util.MathUtil.lerp;
public class CubicSpline {
private final double[] fromValues;
private final double[] toValues;
private final double[] gradients;
public CubicSpline(List<Point> points) {
Collections.sort(points);
this.fromValues = new double[points.size()];
this.toValues = new double[points.size()];
this.gradients = new double[points.size()];
for(int i = 0; i < points.size(); i++) {
fromValues[i] = points.get(i).from;
toValues[i] = points.get(i).to;
gradients[i] = points.get(i).gradient;
}
}
public static double calculate(double in, double[] fromValues, double[] toValues, double[] gradients) {
int pointIdx = floorBinarySearch(in, fromValues) - 1;
int pointIdxLast = fromValues.length - 1;
if(pointIdx < 0) { // If to left of first point return linear function intersecting said point using point's gradient
return gradients[0] * (in - fromValues[0]) + toValues[0];
} else if(pointIdx == pointIdxLast) { // Do same if to right of last point
return gradients[pointIdxLast] * (in - fromValues[pointIdxLast]) + toValues[pointIdxLast];
} else {
double fromLeft = fromValues[pointIdx];
double fromRight = fromValues[pointIdx + 1];
double toLeft = toValues[pointIdx];
double toRight = toValues[pointIdx + 1];
double gradientLeft = gradients[pointIdx];
double gradientRight = gradients[pointIdx + 1];
double fromDelta = fromRight - fromLeft;
double toDelta = toRight - toLeft;
double t = (in - fromLeft) / fromDelta;
return lerp(t, toLeft, toRight) + t * (1.0F - t) * lerp(t, gradientLeft * fromDelta - toDelta,
-gradientRight * fromDelta + toDelta);
}
}
private static int floorBinarySearch(double targetValue, double[] values) {
int left = 0;
int right = values.length;
int idx = right - left;
while(idx > 0) {
int halfDelta = idx / 2;
int mid = left + halfDelta;
if(targetValue < values[mid]) {
idx = halfDelta;
} else {
left = mid + 1;
idx -= halfDelta + 1;
}
}
return left;
}
public double apply(double in) {
return calculate(in, fromValues, toValues, gradients);
}
public record Point(double from, double to, double gradient) implements Comparable<Point> {
@Override
public int compareTo(@NotNull CubicSpline.Point o) {
return Double.compare(from, o.from);
}
}
}
@@ -1,27 +0,0 @@
/*
* Copyright (c) 2020-2025 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.normalizer;
import com.dfsek.terra.api.noise.NoiseSampler;
public class ClampNormalizer extends Normalizer {
private final double min;
private final double max;
public ClampNormalizer(NoiseSampler sampler, double min, double max) {
super(sampler);
this.min = min;
this.max = max;
}
@Override
public double normalize(double in) {
return Math.max(Math.min(in, max), min);
}
}
@@ -1,20 +0,0 @@
package com.dfsek.terra.addons.noise.normalizer;
import com.dfsek.terra.addons.noise.math.CubicSpline;
import com.dfsek.terra.api.noise.NoiseSampler;
public class CubicSplineNoiseSampler extends Normalizer {
private final CubicSpline spline;
public CubicSplineNoiseSampler(NoiseSampler sampler, CubicSpline spline) {
super(sampler);
this.spline = spline;
}
@Override
public double normalize(double in) {
return spline.apply(in);
}
}
@@ -1,47 +0,0 @@
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.Parser.ParseOptions;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.Function;
import java.util.Arrays;
import java.util.Map;
import com.dfsek.terra.api.noise.NoiseSampler;
public class ExpressionNormalizer extends Normalizer {
private final Expression expression;
public ExpressionNormalizer(NoiseSampler sampler, Map<String, Function> functions, String eq, Map<String, Double> vars, ParseOptions parseOptions)
throws ParseException {
super(sampler);
Parser p = new Parser(parseOptions);
Scope scope = new Scope();
// 'in' was used as the invocation variable but conflicts with
// the new 'in' keyword in Paralithic used to denote the end of a let
// expression. To maintain backwards compatibility but also enable the use
// of let expressions, if they're enabled then use the longer 'input'
// invocation variable instead.
if (parseOptions.useLetExpressions()) {
scope.addInvocationVariable("input");
} else {
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);
}
}
@@ -1,28 +0,0 @@
package com.dfsek.terra.addons.noise.normalizer;
import com.dfsek.terra.api.noise.NoiseSampler;
public class LinearMapNormalizer extends Normalizer {
private final double aFrom;
private final double aTo;
private final double bFrom;
private final double bTo;
public LinearMapNormalizer(NoiseSampler sampler, double aFrom, double aTo, double bFrom, double bTo) {
super(sampler);
this.aFrom = aFrom;
this.aTo = aTo;
this.bFrom = bFrom;
this.bTo = bTo;
}
@Override
public double normalize(double in) {
return (in - aFrom) * (aTo - bTo) / (aFrom - bFrom) + aTo;
}
}
@@ -1,30 +0,0 @@
/*
* Copyright (c) 2020-2025 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.normalizer;
import com.dfsek.terra.api.noise.NoiseSampler;
/**
* Normalizer to linearly scale data's range.
*/
public class LinearNormalizer extends Normalizer {
private final double min;
private final double max;
public LinearNormalizer(NoiseSampler sampler, double min, double max) {
super(sampler);
this.min = min;
this.max = max;
}
@Override
public double normalize(double in) {
return (in - min) * (2 / (max - min)) - 1;
}
}
@@ -1,52 +0,0 @@
/*
* Copyright (c) 2020-2025 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.normalizer;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
/**
* Normalizer to redistribute normally distributed data to a continuous distribution via an automatically generated lookup table.
*/
public class NormalNormalizer extends Normalizer {
private final double[] lookup;
public NormalNormalizer(NoiseSampler sampler, int buckets, double mean, double standardDeviation) {
super(sampler);
this.lookup = new double[buckets];
for(int i = 0; i < buckets; i++) {
lookup[i] = MathUtil.normalInverse((double) i / buckets, mean, standardDeviation);
}
}
@Override
public double normalize(double in) {
int start = 0;
int end = lookup.length - 1;
while(start + 1 < end) {
int mid = start + (end - start) / 2;
if(lookup[mid] <= in) {
start = mid;
} else {
end = mid;
}
}
double left = Math.abs(lookup[start] - in);
double right = Math.abs(lookup[end] - in);
double fin;
if(left <= right) {
fin = (double) start / (lookup.length);
} else fin = (double) end / (lookup.length);
return (fin - 0.5) * 2;
}
}
@@ -1,31 +0,0 @@
/*
* Copyright (c) 2020-2025 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.normalizer;
import com.dfsek.terra.api.noise.NoiseSampler;
public abstract class Normalizer implements NoiseSampler {
private final NoiseSampler sampler;
public Normalizer(NoiseSampler sampler) {
this.sampler = sampler;
}
public abstract double normalize(double in);
@Override
public double noise(long seed, double x, double y) {
return normalize(sampler.noise(seed, x, y));
}
@Override
public double noise(long seed, double x, double y, double z) {
return normalize(sampler.noise(seed, x, y, z));
}
}
@@ -1,25 +0,0 @@
/*
* Copyright (c) 2022 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.normalizer;
import com.dfsek.terra.api.noise.NoiseSampler;
public class PosterizationNormalizer extends Normalizer {
private final double stepSize;
public PosterizationNormalizer(NoiseSampler sampler, int steps) {
super(sampler);
this.stepSize = 2.0 / (steps - 1);
}
@Override
public double normalize(double in) {
return (int) Math.round((in + 1) / stepSize) * stepSize - 1;
}
}
@@ -1,15 +0,0 @@
package com.dfsek.terra.addons.noise.normalizer;
import com.dfsek.terra.api.noise.NoiseSampler;
public class ProbabilityNormalizer extends Normalizer {
public ProbabilityNormalizer(NoiseSampler sampler) {
super(sampler);
}
@Override
public double normalize(double in) {
return (in + 1) / 2;
}
}
@@ -1,18 +0,0 @@
package com.dfsek.terra.addons.noise.normalizer;
import com.dfsek.terra.api.noise.NoiseSampler;
public class ScaleNormalizer extends Normalizer {
private final double scale;
public ScaleNormalizer(NoiseSampler sampler, double scale) {
super(sampler);
this.scale = scale;
}
@Override
public double normalize(double in) {
return in * scale;
}
}
@@ -6,20 +6,22 @@ import com.dfsek.paralithic.functions.Function;
import java.util.HashMap;
import java.util.Map;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.paralithic.functions.dynamic.noise.NoiseFunction2;
import com.dfsek.paralithic.functions.dynamic.noise.NoiseFunction3;
import com.dfsek.paralithic.functions.dynamic.noise.SaltedNoiseFunction2;
import com.dfsek.paralithic.functions.dynamic.noise.SaltedNoiseFunction3;
import com.dfsek.terra.addons.noise.config.DimensionApplicableSampler;
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 com.dfsek.terra.addons.noise.paralithic.noise.SaltedNoiseFunction2;
import com.dfsek.terra.addons.noise.paralithic.noise.SaltedNoiseFunction3;
public class FunctionUtil {
private FunctionUtil() { }
public static Map<String, Function> convertFunctionsAndSamplers(Map<String, FunctionTemplate> functions,
Map<String, DimensionApplicableNoiseSampler> samplers)
Map<String, DimensionApplicableSampler> samplers)
throws ParseException {
Map<String, Function> functionMap = new HashMap<>();
for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) {
@@ -5,7 +5,7 @@
* reference the LICENSE file in this module's root directory.
*/
package com.dfsek.terra.addons.noise.paralithic.defined;
package com.dfsek.terra.addons.noise.paralithic;
import com.dfsek.paralithic.Expression;
import com.dfsek.paralithic.eval.parser.Parser;
@@ -1,43 +0,0 @@
/*
* Copyright (c) 2020-2025 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.paralithic.noise;
import com.dfsek.paralithic.functions.dynamic.Context;
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
import com.dfsek.paralithic.node.Statefulness;
import com.dfsek.terra.api.noise.NoiseSampler;
public class NoiseFunction2 implements DynamicFunction {
private final NoiseSampler gen;
public NoiseFunction2(NoiseSampler gen) {
this.gen = gen;
}
@Override
public double eval(double... args) {
throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
}
@Override
public double eval(Context context, double... args) {
return gen.noise(((SeedContext) context).getSeed(), args[0], args[1]);
}
@Override
public int getArgNumber() {
return 2;
}
@Override
public Statefulness statefulness() {
return Statefulness.CONTEXTUAL;
}
}
@@ -1,43 +0,0 @@
/*
* Copyright (c) 2020-2025 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.paralithic.noise;
import com.dfsek.paralithic.functions.dynamic.Context;
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
import com.dfsek.paralithic.node.Statefulness;
import com.dfsek.terra.api.noise.NoiseSampler;
public class NoiseFunction3 implements DynamicFunction {
private final NoiseSampler gen;
public NoiseFunction3(NoiseSampler gen) {
this.gen = gen;
}
@Override
public double eval(double... args) {
throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
}
@Override
public double eval(Context context, double... args) {
return gen.noise(((SeedContext) context).getSeed(), args[0], args[1], args[2]);
}
@Override
public int getArgNumber() {
return 3;
}
@Override
public Statefulness statefulness() {
return Statefulness.CONTEXTUAL;
}
}
@@ -1,37 +0,0 @@
package com.dfsek.terra.addons.noise.paralithic.noise;
import com.dfsek.paralithic.functions.dynamic.Context;
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
import com.dfsek.paralithic.node.Statefulness;
import org.jetbrains.annotations.NotNull;
import com.dfsek.terra.api.noise.NoiseSampler;
public class SaltedNoiseFunction2 implements DynamicFunction {
private final NoiseSampler gen;
public SaltedNoiseFunction2(NoiseSampler gen) {
this.gen = gen;
}
@Override
public double eval(double... args) {
throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
}
@Override
public double eval(Context context, double... args) {
return gen.noise(((SeedContext) context).getSeed() + (long) args[2], args[0], args[1]);
}
@Override
public int getArgNumber() {
return 3;
}
@Override
public @NotNull Statefulness statefulness() {
return Statefulness.CONTEXTUAL;
}
}
@@ -1,37 +0,0 @@
package com.dfsek.terra.addons.noise.paralithic.noise;
import com.dfsek.paralithic.functions.dynamic.Context;
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
import com.dfsek.paralithic.node.Statefulness;
import org.jetbrains.annotations.NotNull;
import com.dfsek.terra.api.noise.NoiseSampler;
public class SaltedNoiseFunction3 implements DynamicFunction {
private final NoiseSampler gen;
public SaltedNoiseFunction3(NoiseSampler gen) {
this.gen = gen;
}
@Override
public double eval(double... args) {
throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
}
@Override
public double eval(Context context, double... args) {
return gen.noise(((SeedContext) context).getSeed() + (long) args[3], args[0], args[1], args[2]);
}
@Override
public int getArgNumber() {
return 4;
}
@Override
public @NotNull Statefulness statefulness() {
return Statefulness.CONTEXTUAL;
}
}
@@ -1,23 +0,0 @@
/*
* Copyright (c) 2020-2025 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.paralithic.noise;
import com.dfsek.paralithic.functions.dynamic.Context;
public class SeedContext implements Context {
private final long seed;
public SeedContext(long seed) {
this.seed = seed;
}
public long getSeed() {
return seed;
}
}
@@ -1,40 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers;
import com.dfsek.terra.api.noise.NoiseSampler;
public class DomainWarpedSampler implements NoiseSampler {
private final NoiseSampler function;
private final NoiseSampler warp;
private final double amplitude;
public DomainWarpedSampler(NoiseSampler function, NoiseSampler warp, double amplitude) {
this.function = function;
this.warp = warp;
this.amplitude = amplitude;
}
@Override
public double noise(long seed, double x, double y) {
return function.noise(seed++,
x + warp.noise(seed++, x, y) * amplitude,
y + warp.noise(seed, x, y) * amplitude
);
}
@Override
public double noise(long seed, double x, double y, double z) {
return function.noise(seed++,
x + warp.noise(seed++, x, y, z) * amplitude,
y + warp.noise(seed++, x, y, z) * amplitude,
z + warp.noise(seed, x, y, z) * amplitude
);
}
}
@@ -1,73 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers;
import java.awt.image.BufferedImage;
import com.dfsek.terra.api.noise.NoiseSampler;
public class ImageSampler implements NoiseSampler {
private final BufferedImage image;
private final Channel channel;
private final double frequency;
public ImageSampler(BufferedImage image, Channel channel, double frequency) {
this.image = image;
this.channel = channel;
this.frequency = frequency;
}
@Override
public double noise(long seed, double x, double y) {
return ((channel.getChannel(image.getRGB(Math.floorMod((int) Math.floor(x * frequency), image.getWidth()),
Math.floorMod((int) Math.floor(y * frequency), image.getHeight()))) / 255D) - 0.5) *
2;
}
@Override
public double noise(long seed, double x, double y, double z) {
return noise(seed, x, y);
}
public enum Channel {
RED {
@Override
public int getChannel(int mashed) {
return (mashed >> 16) & 0xff;
}
},
GREEN {
@Override
public int getChannel(int mashed) {
return (mashed >> 8) & 0xff;
}
},
BLUE {
@Override
public int getChannel(int mashed) {
return mashed & 0xff;
}
},
GRAYSCALE {
@Override
public int getChannel(int mashed) {
return (RED.getChannel(mashed) + GREEN.getChannel(mashed) + BLUE.getChannel(mashed)) / 3;
}
},
ALPHA {
@Override
public int getChannel(int mashed) {
return (mashed >> 24) & 0xff;
}
};
public abstract int getChannel(int mashed);
}
}
@@ -1,63 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers;
import com.dfsek.terra.api.noise.NoiseSampler;
public class KernelSampler implements NoiseSampler {
private final double[][] kernel;
private final NoiseSampler in;
private double frequency = 1;
public KernelSampler(double[][] kernel, NoiseSampler in) {
this.kernel = kernel;
this.in = in;
}
public void setFrequency(double frequency) {
this.frequency = frequency;
}
@Override
public double noise(long seed, double x, double y) {
x *= frequency;
y *= frequency;
double accumulator = 0;
for(int kx = 0; kx < kernel.length; kx++) {
for(int ky = 0; ky < kernel[kx].length; ky++) {
double k = kernel[kx][ky];
if(k != 0) {
accumulator += in.noise(seed, x + kx, y + ky) * k;
}
}
}
return accumulator;
}
@Override
public double noise(long seed, double x, double y, double z) {
x *= frequency;
y *= frequency;
z *= frequency;
double accumulator = 0;
for(int kx = 0; kx < kernel.length; kx++) {
for(int ky = 0; ky < kernel[kx].length; ky++) {
double k = kernel[kx][ky];
if(k != 0) {
accumulator += in.noise(seed, x + kx, y, z + ky) * k;
}
}
}
return accumulator;
}
}
@@ -1,27 +0,0 @@
package com.dfsek.terra.addons.noise.samplers;
import com.dfsek.terra.api.noise.NoiseSampler;
public class LinearHeightmapSampler implements NoiseSampler {
private final NoiseSampler sampler;
private final double scale;
private final double base;
public LinearHeightmapSampler(NoiseSampler sampler, double scale, double base) {
this.sampler = sampler;
this.scale = scale;
this.base = base;
}
@Override
public double noise(long seed, double x, double y) {
return noise(seed, x, 0, y);
}
@Override
public double noise(long seed, double x, double y, double z) {
return -y + base + sampler.noise(seed, x, y, z) * scale;
}
}
@@ -1,27 +0,0 @@
package com.dfsek.terra.addons.noise.samplers;
import com.dfsek.terra.api.noise.NoiseSampler;
public class TranslateSampler implements NoiseSampler {
private final NoiseSampler sampler;
private final double dx, dy, dz;
public TranslateSampler(NoiseSampler sampler, double dx, double dy, double dz) {
this.sampler = sampler;
this.dx = dx;
this.dy = dy;
this.dz = dz;
}
@Override
public double noise(long seed, double x, double y) {
return sampler.noise(seed, x - dx, y - dz);
}
@Override
public double noise(long seed, double x, double y, double z) {
return sampler.noise(seed, x - dx, y - dy, z - dz);
}
}
@@ -1,25 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.arithmetic;
import com.dfsek.terra.api.noise.NoiseSampler;
public class AdditionSampler extends BinaryArithmeticSampler {
public AdditionSampler(NoiseSampler left, NoiseSampler right) {
super(left, right);
}
@Override
public double operate(double left, double right) {
return left + right;
}
@Override
public double[] operateDerivative(double[] left, double[] right) {
int dimensions = left.length;
double[] out = new double[dimensions];
for(int i = 0; i < dimensions; i++) {
out[i] = left[i] + right[i];
}
return out;
}
}
@@ -1,44 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.arithmetic;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
public abstract class BinaryArithmeticSampler implements DerivativeNoiseSampler {
private final NoiseSampler left;
private final NoiseSampler right;
protected BinaryArithmeticSampler(NoiseSampler left, NoiseSampler right) {
this.left = left;
this.right = right;
}
@Override
public boolean isDifferentiable() {
return DerivativeNoiseSampler.isDifferentiable(left) && DerivativeNoiseSampler.isDifferentiable(right);
}
@Override
public double noise(long seed, double x, double y) {
return operate(left.noise(seed, x, y), right.noise(seed, x, y));
}
@Override
public double noise(long seed, double x, double y, double z) {
return operate(left.noise(seed, x, y, z), right.noise(seed, x, y, z));
}
@Override
public double[] noised(long seed, double x, double y) {
return operateDerivative(((DerivativeNoiseSampler)left).noised(seed, x, y), ((DerivativeNoiseSampler)right).noised(seed, x, y));
}
@Override
public double[] noised(long seed, double x, double y, double z) {
return operateDerivative(((DerivativeNoiseSampler)left).noised(seed, x, y, z), ((DerivativeNoiseSampler)right).noised(seed, x, y, z));
}
public abstract double operate(double left, double right);
public abstract double[] operateDerivative(double[] left, double[] right);
}
@@ -1,26 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.arithmetic;
import com.dfsek.terra.api.noise.NoiseSampler;
public class DivisionSampler extends BinaryArithmeticSampler {
public DivisionSampler(NoiseSampler left, NoiseSampler right) {
super(left, right);
}
@Override
public double operate(double left, double right) {
return left / right;
}
@Override
public double[] operateDerivative(double[] left, double[] right) {
int dimensions = left.length;
double[] out = new double[dimensions];
out[0] = left[0] / right[0];
for(int i = 1; i < dimensions; i++) {
out[i] = (left[i] * right[0] - left[0] * right[i]) / (right[0] * right[0]);
}
return out;
}
}
@@ -1,22 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.arithmetic;
import com.dfsek.terra.api.noise.NoiseSampler;
public class MaxSampler extends BinaryArithmeticSampler {
public MaxSampler(NoiseSampler left, NoiseSampler right) {
super(left, right);
}
@Override
public double operate(double left, double right) {
return Math.max(left, right);
}
@Override
public double[] operateDerivative(double[] left, double[] right) {
double leftValue = left[0];
double rightValue = right[0];
return leftValue > rightValue ? left : right;
}
}
@@ -1,22 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.arithmetic;
import com.dfsek.terra.api.noise.NoiseSampler;
public class MinSampler extends BinaryArithmeticSampler {
public MinSampler(NoiseSampler left, NoiseSampler right) {
super(left, right);
}
@Override
public double operate(double left, double right) {
return Math.min(left, right);
}
@Override
public double[] operateDerivative(double[] left, double[] right) {
double leftValue = left[0];
double rightValue = right[0];
return leftValue < rightValue ? left : right;
}
}
@@ -1,26 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.arithmetic;
import com.dfsek.terra.api.noise.NoiseSampler;
public class MultiplicationSampler extends BinaryArithmeticSampler {
public MultiplicationSampler(NoiseSampler left, NoiseSampler right) {
super(left, right);
}
@Override
public double operate(double left, double right) {
return left * right;
}
@Override
public double[] operateDerivative(double[] left, double[] right) {
int dimensions = left.length;
double[] out = new double[dimensions];
out[0] = left[0] * right[0];
for(int i = 1; i < dimensions; i++) {
out[i] = left[i] * right[0] + left[0] * right[i];
}
return out;
}
}
@@ -1,25 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.arithmetic;
import com.dfsek.terra.api.noise.NoiseSampler;
public class SubtractionSampler extends BinaryArithmeticSampler {
public SubtractionSampler(NoiseSampler left, NoiseSampler right) {
super(left, right);
}
@Override
public double operate(double left, double right) {
return left - right;
}
@Override
public double[] operateDerivative(double[] left, double[] right) {
int dimensions = left.length;
double[] out = new double[dimensions];
for(int i = 0; i < dimensions; i++) {
out[i] = left[i] - right[i];
}
return out;
}
}
@@ -1,425 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2Sampler;
import com.dfsek.terra.api.noise.NoiseSampler;
/**
* NoiseSampler implementation for Cellular (Voronoi/Worley) Noise.
*/
public class CellularSampler extends NoiseFunction {
private static final double[] RAND_VECS_3D = {
-0.7292736885d, -0.6618439697d, 0.1735581948d, 0, 0.790292081d, -0.5480887466d, -0.2739291014d, 0, 0.7217578935d, 0.6226212466d,
-0.3023380997d, 0, 0.565683137d, -0.8208298145d, -0.0790000257d, 0, 0.760049034d, -0.5555979497d, -0.3370999617d, 0,
0.3713945616d, 0.5011264475d, 0.7816254623d, 0, -0.1277062463d, -0.4254438999d, -0.8959289049d, 0, -0.2881560924d,
-0.5815838982d, 0.7607405838d, 0, 0.5849561111d, -0.662820239d, -0.4674352136d, 0, 0.3307171178d, 0.0391653737d, 0.94291689d, 0,
0.8712121778d, -0.4113374369d, -0.2679381538d, 0, 0.580981015d, 0.7021915846d, 0.4115677815d, 0, 0.503756873d, 0.6330056931d,
-0.5878203852d, 0, 0.4493712205d, 0.601390195d, 0.6606022552d, 0, -0.6878403724d, 0.09018890807d, -0.7202371714d, 0,
-0.5958956522d, -0.6469350577d, 0.475797649d, 0, -0.5127052122d, 0.1946921978d, -0.8361987284d, 0, -0.9911507142d,
-0.05410276466d, -0.1212153153d, 0, -0.2149721042d, 0.9720882117d, -0.09397607749d, 0, -0.7518650936d, -0.5428057603d,
0.3742469607d, 0, 0.5237068895d, 0.8516377189d, -0.02107817834d, 0, 0.6333504779d, 0.1926167129d, -0.7495104896d, 0,
-0.06788241606d, 0.3998305789d, 0.9140719259d, 0, -0.5538628599d, -0.4729896695d, -0.6852128902d, 0, -0.7261455366d,
-0.5911990757d, 0.3509933228d, 0, -0.9229274737d, -0.1782808786d, 0.3412049336d, 0, -0.6968815002d, 0.6511274338d,
0.3006480328d, 0, 0.9608044783d, -0.2098363234d, -0.1811724921d, 0, 0.06817146062d, -0.9743405129d, 0.2145069156d, 0,
-0.3577285196d, -0.6697087264d, -0.6507845481d, 0, -0.1868621131d, 0.7648617052d, -0.6164974636d, 0, -0.6541697588d,
0.3967914832d, 0.6439087246d, 0, 0.6993340405d, -0.6164538506d, 0.3618239211d, 0, -0.1546665739d, 0.6291283928d, 0.7617583057d,
0, -0.6841612949d, -0.2580482182d, -0.6821542638d, 0, 0.5383980957d, 0.4258654885d, 0.7271630328d, 0, -0.5026987823d,
-0.7939832935d, -0.3418836993d, 0, 0.3202971715d, 0.2834415347d, 0.9039195862d, 0, 0.8683227101d, -0.0003762656404d,
-0.4959995258d, 0, 0.791120031d, -0.08511045745d, 0.6057105799d, 0, -0.04011016052d, -0.4397248749d, 0.8972364289d, 0,
0.9145119872d, 0.3579346169d, -0.1885487608d, 0, -0.9612039066d, -0.2756484276d, 0.01024666929d, 0, 0.6510361721d,
-0.2877799159d, -0.7023778346d, 0, -0.2041786351d, 0.7365237271d, 0.644859585d, 0, -0.7718263711d, 0.3790626912d, 0.5104855816d,
0, -0.3060082741d, -0.7692987727d, 0.5608371729d, 0, 0.454007341d, -0.5024843065d, 0.7357899537d, 0, 0.4816795475d,
0.6021208291d, -0.6367380315d, 0, 0.6961980369d, -0.3222197429d, 0.641469197d, 0, -0.6532160499d, -0.6781148932d, 0.3368515753d,
0, 0.5089301236d, -0.6154662304d, -0.6018234363d, 0, -0.1635919754d, -0.9133604627d, -0.372840892d, 0, 0.52408019d,
-0.8437664109d, 0.1157505864d, 0, 0.5902587356d, 0.4983817807d, -0.6349883666d, 0, 0.5863227872d, 0.494764745d, 0.6414307729d,
0, 0.6779335087d, 0.2341345225d, 0.6968408593d, 0, 0.7177054546d, -0.6858979348d, 0.120178631d, 0, -0.5328819713d,
-0.5205125012d, 0.6671608058d, 0, -0.8654874251d, -0.0700727088d, -0.4960053754d, 0, -0.2861810166d, 0.7952089234d,
0.5345495242d, 0, -0.04849529634d, 0.9810836427d, -0.1874115585d, 0, -0.6358521667d, 0.6058348682d, 0.4781800233d, 0,
0.6254794696d, -0.2861619734d, 0.7258696564d, 0, -0.2585259868d, 0.5061949264d, -0.8227581726d, 0, 0.02136306781d,
0.5064016808d, -0.8620330371d, 0, 0.200111773d, 0.8599263484d, 0.4695550591d, 0, 0.4743561372d, 0.6014985084d, -0.6427953014d,
0, 0.6622993731d, -0.5202474575d, -0.5391679918d, 0, 0.08084972818d, -0.6532720452d, 0.7527940996d, 0, -0.6893687501d,
0.0592860349d, 0.7219805347d, 0, -0.1121887082d, -0.9673185067d, 0.2273952515d, 0, 0.7344116094d, 0.5979668656d, -0.3210532909d,
0, 0.5789393465d, -0.2488849713d, 0.7764570201d, 0, 0.6988182827d, 0.3557169806d, -0.6205791146d, 0, -0.8636845529d,
-0.2748771249d, -0.4224826141d, 0, -0.4247027957d, -0.4640880967d, 0.777335046d, 0, 0.5257722489d, -0.8427017621d,
0.1158329937d, 0, 0.9343830603d, 0.316302472d, -0.1639543925d, 0, -0.1016836419d, -0.8057303073d, -0.5834887393d, 0,
-0.6529238969d, 0.50602126d, -0.5635892736d, 0, -0.2465286165d, -0.9668205684d, -0.06694497494d, 0, -0.9776897119d,
-0.2099250524d, -0.007368825344d, 0, 0.7736893337d, 0.5734244712d, 0.2694238123d, 0, -0.6095087895d, 0.4995678998d,
0.6155736747d, 0, 0.5794535482d, 0.7434546771d, 0.3339292269d, 0, -0.8226211154d, 0.08142581855d, 0.5627293636d, 0,
-0.510385483d, 0.4703667658d, 0.7199039967d, 0, -0.5764971849d, -0.07231656274d, -0.8138926898d, 0, 0.7250628871d,
0.3949971505d, -0.5641463116d, 0, -0.1525424005d, 0.4860840828d, -0.8604958341d, 0, -0.5550976208d, -0.4957820792d,
0.667882296d, 0, -0.1883614327d, 0.9145869398d, 0.357841725d, 0, 0.7625556724d, -0.5414408243d, -0.3540489801d, 0,
-0.5870231946d, -0.3226498013d, -0.7424963803d, 0, 0.3051124198d, 0.2262544068d, -0.9250488391d, 0, 0.6379576059d, 0.577242424d,
-0.5097070502d, 0, -0.5966775796d, 0.1454852398d, -0.7891830656d, 0, -0.658330573d, 0.6555487542d, -0.3699414651d, 0,
0.7434892426d, 0.2351084581d, 0.6260573129d, 0, 0.5562114096d, 0.8264360377d, -0.0873632843d, 0, -0.3028940016d, -0.8251527185d,
0.4768419182d, 0, 0.1129343818d, -0.985888439d, -0.1235710781d, 0, 0.5937652891d, -0.5896813806d, 0.5474656618d, 0,
0.6757964092d, -0.5835758614d, -0.4502648413d, 0, 0.7242302609d, -0.1152719764d, 0.6798550586d, 0, -0.9511914166d,
0.0753623979d, -0.2992580792d, 0, 0.2539470961d, -0.1886339355d, 0.9486454084d, 0, 0.571433621d, -0.1679450851d, -0.8032795685d,
0, -0.06778234979d, 0.3978269256d, 0.9149531629d, 0, 0.6074972649d, 0.733060024d, -0.3058922593d, 0, -0.5435478392d,
0.1675822484d, 0.8224791405d, 0, -0.5876678086d, -0.3380045064d, -0.7351186982d, 0, -0.7967562402d, 0.04097822706d,
-0.6029098428d, 0, -0.1996350917d, 0.8706294745d, 0.4496111079d, 0, -0.02787660336d, -0.9106232682d, -0.4122962022d, 0,
-0.7797625996d, -0.6257634692d, 0.01975775581d, 0, -0.5211232846d, 0.7401644346d, -0.4249554471d, 0, 0.8575424857d,
0.4053272873d, -0.3167501783d, 0, 0.1045223322d, 0.8390195772d, -0.5339674439d, 0, 0.3501822831d, 0.9242524096d, -0.1520850155d,
0, 0.1987849858d, 0.07647613266d, 0.9770547224d, 0, 0.7845996363d, 0.6066256811d, -0.1280964233d, 0, 0.09006737436d,
-0.9750989929d, -0.2026569073d, 0, -0.8274343547d, -0.542299559d, 0.1458203587d, 0, -0.3485797732d, -0.415802277d, 0.840000362d,
0, -0.2471778936d, -0.7304819962d, -0.6366310879d, 0, -0.3700154943d, 0.8577948156d, 0.3567584454d, 0, 0.5913394901d,
-0.548311967d, -0.5913303597d, 0, 0.1204873514d, -0.7626472379d, -0.6354935001d, 0, 0.616959265d, 0.03079647928d, 0.7863922953d,
0, 0.1258156836d, -0.6640829889d, -0.7369967419d, 0, -0.6477565124d, -0.1740147258d, -0.7417077429d, 0, 0.6217889313d,
-0.7804430448d, -0.06547655076d, 0, 0.6589943422d, -0.6096987708d, 0.4404473475d, 0, -0.2689837504d, -0.6732403169d,
-0.6887635427d, 0, -0.3849775103d, 0.5676542638d, 0.7277093879d, 0, 0.5754444408d, 0.8110471154d, -0.1051963504d, 0,
0.9141593684d, 0.3832947817d, 0.131900567d, 0, -0.107925319d, 0.9245493968d, 0.3654593525d, 0, 0.377977089d, 0.3043148782d,
0.8743716458d, 0, -0.2142885215d, -0.8259286236d, 0.5214617324d, 0, 0.5802544474d, 0.4148098596d, -0.7008834116d, 0,
-0.1982660881d, 0.8567161266d, -0.4761596756d, 0, -0.03381553704d, 0.3773180787d, -0.9254661404d, 0, -0.6867922841d,
-0.6656597827d, 0.2919133642d, 0, 0.7731742607d, -0.2875793547d, -0.5652430251d, 0, -0.09655941928d, 0.9193708367d,
-0.3813575004d, 0, 0.2715702457d, -0.9577909544d, -0.09426605581d, 0, 0.2451015704d, -0.6917998565d, -0.6792188003d, 0,
0.977700782d, -0.1753855374d, 0.1155036542d, 0, -0.5224739938d, 0.8521606816d, 0.02903615945d, 0, -0.7734880599d,
-0.5261292347d, 0.3534179531d, 0, -0.7134492443d, -0.269547243d, 0.6467878011d, 0, 0.1644037271d, 0.5105846203d, -0.8439637196d,
0, 0.6494635788d, 0.05585611296d, 0.7583384168d, 0, -0.4711970882d, 0.5017280509d, -0.7254255765d, 0, -0.6335764307d,
-0.2381686273d, -0.7361091029d, 0, -0.9021533097d, -0.270947803d, -0.3357181763d, 0, -0.3793711033d, 0.872258117d,
0.3086152025d, 0, -0.6855598966d, -0.3250143309d, 0.6514394162d, 0, 0.2900942212d, -0.7799057743d, -0.5546100667d, 0,
-0.2098319339d, 0.85037073d, 0.4825351604d, 0, -0.4592603758d, 0.6598504336d, -0.5947077538d, 0, 0.8715945488d, 0.09616365406d,
-0.4807031248d, 0, -0.6776666319d, 0.7118504878d, -0.1844907016d, 0, 0.7044377633d, 0.312427597d, 0.637304036d, 0,
-0.7052318886d, -0.2401093292d, -0.6670798253d, 0, 0.081921007d, -0.7207336136d, -0.6883545647d, 0, -0.6993680906d,
-0.5875763221d, -0.4069869034d, 0, -0.1281454481d, 0.6419895885d, 0.7559286424d, 0, -0.6337388239d, -0.6785471501d,
-0.3714146849d, 0, 0.5565051903d, -0.2168887573d, -0.8020356851d, 0, -0.5791554484d, 0.7244372011d, -0.3738578718d, 0,
0.1175779076d, -0.7096451073d, 0.6946792478d, 0, -0.6134619607d, 0.1323631078d, 0.7785527795d, 0, 0.6984635305d,
-0.02980516237d, -0.715024719d, 0, 0.8318082963d, -0.3930171956d, 0.3919597455d, 0, 0.1469576422d, 0.05541651717d,
-0.9875892167d, 0, 0.708868575d, -0.2690503865d, 0.6520101478d, 0, 0.2726053183d, 0.67369766d, -0.68688995d, 0, -0.6591295371d,
0.3035458599d, -0.6880466294d, 0, 0.4815131379d, -0.7528270071d, 0.4487723203d, 0, 0.9430009463d, 0.1675647412d, -0.2875261255d,
0, 0.434802957d, 0.7695304522d, -0.4677277752d, 0, 0.3931996188d, 0.594473625d, 0.7014236729d, 0, 0.7254336655d, -0.603925654d,
0.3301814672d, 0, 0.7590235227d, -0.6506083235d, 0.02433313207d, 0, -0.8552768592d, -0.3430042733d, 0.3883935666d, 0,
-0.6139746835d, 0.6981725247d, 0.3682257648d, 0, -0.7465905486d, -0.5752009504d, 0.3342849376d, 0, 0.5730065677d, 0.810555537d,
-0.1210916791d, 0, -0.9225877367d, -0.3475211012d, -0.167514036d, 0, -0.7105816789d, -0.4719692027d, -0.5218416899d, 0,
-0.08564609717d, 0.3583001386d, 0.929669703d, 0, -0.8279697606d, -0.2043157126d, 0.5222271202d, 0, 0.427944023d, 0.278165994d,
0.8599346446d, 0, 0.5399079671d, -0.7857120652d, -0.3019204161d, 0, 0.5678404253d, -0.5495413974d, -0.6128307303d, 0,
-0.9896071041d, 0.1365639107d, -0.04503418428d, 0, -0.6154342638d, -0.6440875597d, 0.4543037336d, 0, 0.1074204368d,
-0.7946340692d, 0.5975094525d, 0, -0.3595449969d, -0.8885529948d, 0.28495784d, 0, -0.2180405296d, 0.1529888965d, 0.9638738118d,
0, -0.7277432317d, -0.6164050508d, -0.3007234646d, 0, 0.7249729114d, -0.00669719484d, 0.6887448187d, 0, -0.5553659455d,
-0.5336586252d, 0.6377908264d, 0, 0.5137558015d, 0.7976208196d, -0.3160000073d, 0, -0.3794024848d, 0.9245608561d,
-0.03522751494d, 0, 0.8229248658d, 0.2745365933d, -0.4974176556d, 0, -0.5404114394d, 0.6091141441d, 0.5804613989d, 0,
0.8036581901d, -0.2703029469d, 0.5301601931d, 0, 0.6044318879d, 0.6832968393d, 0.4095943388d, 0, 0.06389988817d, 0.9658208605d,
-0.2512108074d, 0, 0.1087113286d, 0.7402471173d, -0.6634877936d, 0, -0.713427712d, -0.6926784018d, 0.1059128479d, 0,
0.6458897819d, -0.5724548511d, -0.5050958653d, 0, -0.6553931414d, 0.7381471625d, 0.159995615d, 0, 0.3910961323d, 0.9188871375d,
-0.05186755998d, 0, -0.4879022471d, -0.5904376907d, 0.6429111375d, 0, 0.6014790094d, 0.7707441366d, -0.2101820095d, 0,
-0.5677173047d, 0.7511360995d, 0.3368851762d, 0, 0.7858573506d, 0.226674665d, 0.5753666838d, 0, -0.4520345543d, -0.604222686d,
-0.6561857263d, 0, 0.002272116345d, 0.4132844051d, -0.9105991643d, 0, -0.5815751419d, -0.5162925989d, 0.6286591339d, 0,
-0.03703704785d, 0.8273785755d, 0.5604221175d, 0, -0.5119692504d, 0.7953543429d, -0.3244980058d, 0, -0.2682417366d,
-0.9572290247d, -0.1084387619d, 0, -0.2322482736d, -0.9679131102d, -0.09594243324d, 0, 0.3554328906d, -0.8881505545d,
0.2913006227d, 0, 0.7346520519d, -0.4371373164d, 0.5188422971d, 0, 0.9985120116d, 0.04659011161d, -0.02833944577d, 0,
-0.3727687496d, -0.9082481361d, 0.1900757285d, 0, 0.91737377d, -0.3483642108d, 0.1925298489d, 0, 0.2714911074d, 0.4147529736d,
-0.8684886582d, 0, 0.5131763485d, -0.7116334161d, 0.4798207128d, 0, -0.8737353606d, 0.18886992d, -0.4482350644d, 0,
0.8460043821d, -0.3725217914d, 0.3814499973d, 0, 0.8978727456d, -0.1780209141d, -0.4026575304d, 0, 0.2178065647d,
-0.9698322841d, -0.1094789531d, 0, -0.1518031304d, -0.7788918132d, -0.6085091231d, 0, -0.2600384876d, -0.4755398075d,
-0.8403819825d, 0, 0.572313509d, -0.7474340931d, -0.3373418503d, 0, -0.7174141009d, 0.1699017182d, -0.6756111411d, 0,
-0.684180784d, 0.02145707593d, -0.7289967412d, 0, -0.2007447902d, 0.06555605789d, -0.9774476623d, 0, -0.1148803697d,
-0.8044887315d, 0.5827524187d, 0, -0.7870349638d, 0.03447489231d, 0.6159443543d, 0, -0.2015596421d, 0.6859872284d,
0.6991389226d, 0, -0.08581082512d, -0.10920836d, -0.9903080513d, 0, 0.5532693395d, 0.7325250401d, -0.396610771d, 0,
-0.1842489331d, -0.9777375055d, -0.1004076743d, 0, 0.0775473789d, -0.9111505856d, 0.4047110257d, 0, 0.1399838409d,
0.7601631212d, -0.6344734459d, 0, 0.4484419361d, -0.845289248d, 0.2904925424d, 0
};
private static final double[] RAND_VECS_2D = {
-0.2700222198d, -0.9628540911d, 0.3863092627d, -0.9223693152d, 0.04444859006d, -0.999011673d, -0.5992523158d, -0.8005602176d,
-0.7819280288d, 0.6233687174d, 0.9464672271d, 0.3227999196d, -0.6514146797d, -0.7587218957d, 0.9378472289d, 0.347048376d,
-0.8497875957d, -0.5271252623d, -0.879042592d, 0.4767432447d, -0.892300288d, -0.4514423508d, -0.379844434d, -0.9250503802d,
-0.9951650832d, 0.0982163789d, 0.7724397808d, -0.6350880136d, 0.7573283322d, -0.6530343002d, -0.9928004525d, -0.119780055d,
-0.0532665713d, 0.9985803285d, 0.9754253726d, -0.2203300762d, -0.7665018163d, 0.6422421394d, 0.991636706d, 0.1290606184d,
-0.994696838d, 0.1028503788d, -0.5379205513d, -0.84299554d, 0.5022815471d, -0.8647041387d, 0.4559821461d, -0.8899889226d,
-0.8659131224d, -0.5001944266d, 0.0879458407d, -0.9961252577d, -0.5051684983d, 0.8630207346d, 0.7753185226d, -0.6315704146d,
-0.6921944612d, 0.7217110418d, -0.5191659449d, -0.8546734591d, 0.8978622882d, -0.4402764035d, -0.1706774107d, 0.9853269617d,
-0.9353430106d, -0.3537420705d, -0.9992404798d, 0.03896746794d, -0.2882064021d, -0.9575683108d, -0.9663811329d, 0.2571137995d,
-0.8759714238d, -0.4823630009d, -0.8303123018d, -0.5572983775d, 0.05110133755d, -0.9986934731d, -0.8558373281d, -0.5172450752d,
0.09887025282d, 0.9951003332d, 0.9189016087d, 0.3944867976d, -0.2439375892d, -0.9697909324d, -0.8121409387d, -0.5834613061d,
-0.9910431363d, 0.1335421355d, 0.8492423985d, -0.5280031709d, -0.9717838994d, -0.2358729591d, 0.9949457207d, 0.1004142068d,
0.6241065508d, -0.7813392434d, 0.662910307d, 0.7486988212d, -0.7197418176d, 0.6942418282d, -0.8143370775d, -0.5803922158d,
0.104521054d, -0.9945226741d, -0.1065926113d, -0.9943027784d, 0.445799684d, -0.8951327509d, 0.105547406d, 0.9944142724d,
-0.992790267d, 0.1198644477d, -0.8334366408d, 0.552615025d, 0.9115561563d, -0.4111755999d, 0.8285544909d, -0.5599084351d,
0.7217097654d, -0.6921957921d, 0.4940492677d, -0.8694339084d, -0.3652321272d, -0.9309164803d, -0.9696606758d, 0.2444548501d,
0.08925509731d, -0.996008799d, 0.5354071276d, -0.8445941083d, -0.1053576186d, 0.9944343981d, -0.9890284586d, 0.1477251101d,
0.004856104961d, 0.9999882091d, 0.9885598478d, 0.1508291331d, 0.9286129562d, -0.3710498316d, -0.5832393863d, -0.8123003252d,
0.3015207509d, 0.9534596146d, -0.9575110528d, 0.2883965738d, 0.9715802154d, -0.2367105511d, 0.229981792d, 0.9731949318d,
0.955763816d, -0.2941352207d, 0.740956116d, 0.6715534485d, -0.9971513787d, -0.07542630764d, 0.6905710663d, -0.7232645452d,
-0.290713703d, -0.9568100872d, 0.5912777791d, -0.8064679708d, -0.9454592212d, -0.325740481d, 0.6664455681d, 0.74555369d,
0.6236134912d, 0.7817328275d, 0.9126993851d, -0.4086316587d, -0.8191762011d, 0.5735419353d, -0.8812745759d, -0.4726046147d,
0.9953313627d, 0.09651672651d, 0.9855650846d, -0.1692969699d, -0.8495980887d, 0.5274306472d, 0.6174853946d, -0.7865823463d,
0.8508156371d, 0.52546432d, 0.9985032451d, -0.05469249926d, 0.1971371563d, -0.9803759185d, 0.6607855748d, -0.7505747292d,
-0.03097494063d, 0.9995201614d, -0.6731660801d, 0.739491331d, -0.7195018362d, -0.6944905383d, 0.9727511689d, 0.2318515979d,
0.9997059088d, -0.0242506907d, 0.4421787429d, -0.8969269532d, 0.9981350961d, -0.061043673d, -0.9173660799d, -0.3980445648d,
-0.8150056635d, -0.5794529907d, -0.8789331304d, 0.4769450202d, 0.0158605829d, 0.999874213d, -0.8095464474d, 0.5870558317d,
-0.9165898907d, -0.3998286786d, -0.8023542565d, 0.5968480938d, -0.5176737917d, 0.8555780767d, -0.8154407307d, -0.5788405779d,
0.4022010347d, -0.9155513791d, -0.9052556868d, -0.4248672045d, 0.7317445619d, 0.6815789728d, -0.5647632201d, -0.8252529947d,
-0.8403276335d, -0.5420788397d, -0.9314281527d, 0.363925262d, 0.5238198472d, 0.8518290719d, 0.7432803869d, -0.6689800195d,
-0.985371561d, -0.1704197369d, 0.4601468731d, 0.88784281d, 0.825855404d, 0.5638819483d, 0.6182366099d, 0.7859920446d,
0.8331502863d, -0.553046653d, 0.1500307506d, 0.9886813308d, -0.662330369d, -0.7492119075d, -0.668598664d, 0.743623444d,
0.7025606278d, 0.7116238924d, -0.5419389763d, -0.8404178401d, -0.3388616456d, 0.9408362159d, 0.8331530315d, 0.5530425174d,
-0.2989720662d, -0.9542618632d, 0.2638522993d, 0.9645630949d, 0.124108739d, -0.9922686234d, -0.7282649308d, -0.6852956957d,
0.6962500149d, 0.7177993569d, -0.9183535368d, 0.3957610156d, -0.6326102274d, -0.7744703352d, -0.9331891859d, -0.359385508d,
-0.1153779357d, -0.9933216659d, 0.9514974788d, -0.3076565421d, -0.08987977445d, -0.9959526224d, 0.6678496916d, 0.7442961705d,
0.7952400393d, -0.6062947138d, -0.6462007402d, -0.7631674805d, -0.2733598753d, 0.9619118351d, 0.9669590226d, -0.254931851d,
-0.9792894595d, 0.2024651934d, -0.5369502995d, -0.8436138784d, -0.270036471d, -0.9628500944d, -0.6400277131d, 0.7683518247d,
-0.7854537493d, -0.6189203566d, 0.06005905383d, -0.9981948257d, -0.02455770378d, 0.9996984141d, -0.65983623d, 0.751409442d,
-0.6253894466d, -0.7803127835d, -0.6210408851d, -0.7837781695d, 0.8348888491d, 0.5504185768d, -0.1592275245d, 0.9872419133d,
0.8367622488d, 0.5475663786d, -0.8675753916d, -0.4973056806d, -0.2022662628d, -0.9793305667d, 0.9399189937d, 0.3413975472d,
0.9877404807d, -0.1561049093d, -0.9034455656d, 0.4287028224d, 0.1269804218d, -0.9919052235d, -0.3819600854d, 0.924178821d,
0.9754625894d, 0.2201652486d, -0.3204015856d, -0.9472818081d, -0.9874760884d, 0.1577687387d, 0.02535348474d, -0.9996785487d,
0.4835130794d, -0.8753371362d, -0.2850799925d, -0.9585037287d, -0.06805516006d, -0.99768156d, -0.7885244045d, -0.6150034663d,
0.3185392127d, -0.9479096845d, 0.8880043089d, 0.4598351306d, 0.6476921488d, -0.7619021462d, 0.9820241299d, 0.1887554194d,
0.9357275128d, -0.3527237187d, -0.8894895414d, 0.4569555293d, 0.7922791302d, 0.6101588153d, 0.7483818261d, 0.6632681526d,
-0.7288929755d, -0.6846276581d, 0.8729032783d, -0.4878932944d, 0.8288345784d, 0.5594937369d, 0.08074567077d, 0.9967347374d,
0.9799148216d, -0.1994165048d, -0.580730673d, -0.8140957471d, -0.4700049791d, -0.8826637636d, 0.2409492979d, 0.9705377045d,
0.9437816757d, -0.3305694308d, -0.8927998638d, -0.4504535528d, -0.8069622304d, 0.5906030467d, 0.06258973166d, 0.9980393407d,
-0.9312597469d, 0.3643559849d, 0.5777449785d, 0.8162173362d, -0.3360095855d, -0.941858566d, 0.697932075d, -0.7161639607d,
-0.002008157227d, -0.9999979837d, -0.1827294312d, -0.9831632392d, -0.6523911722d, 0.7578824173d, -0.4302626911d, -0.9027037258d,
-0.9985126289d, -0.05452091251d, -0.01028102172d, -0.9999471489d, -0.4946071129d, 0.8691166802d, -0.2999350194d, 0.9539596344d,
0.8165471961d, 0.5772786819d, 0.2697460475d, 0.962931498d, -0.7306287391d, -0.6827749597d, -0.7590952064d, -0.6509796216d,
-0.907053853d, 0.4210146171d, -0.5104861064d, -0.8598860013d, 0.8613350597d, 0.5080373165d, 0.5007881595d, -0.8655698812d,
-0.654158152d, 0.7563577938d, -0.8382755311d, -0.545246856d, 0.6940070834d, 0.7199681717d, 0.06950936031d, 0.9975812994d,
0.1702942185d, -0.9853932612d, 0.2695973274d, 0.9629731466d, 0.5519612192d, -0.8338697815d, 0.225657487d, -0.9742067022d,
0.4215262855d, -0.9068161835d, 0.4881873305d, -0.8727388672d, -0.3683854996d, -0.9296731273d, -0.9825390578d, 0.1860564427d,
0.81256471d, 0.5828709909d, 0.3196460933d, -0.9475370046d, 0.9570913859d, 0.2897862643d, -0.6876655497d, -0.7260276109d,
-0.9988770922d, -0.047376731d, -0.1250179027d, 0.992154486d, -0.8280133617d, 0.560708367d, 0.9324863769d, -0.3612051451d,
0.6394653183d, 0.7688199442d, -0.01623847064d, -0.9998681473d, -0.9955014666d, -0.09474613458d, -0.81453315d, 0.580117012d,
0.4037327978d, -0.9148769469d, 0.9944263371d, 0.1054336766d, -0.1624711654d, 0.9867132919d, -0.9949487814d, -0.100383875d,
-0.6995302564d, 0.7146029809d, 0.5263414922d, -0.85027327d, -0.5395221479d, 0.841971408d, 0.6579370318d, 0.7530729462d,
0.01426758847d, -0.9998982128d, -0.6734383991d, 0.7392433447d, 0.639412098d, -0.7688642071d, 0.9211571421d, 0.3891908523d,
-0.146637214d, -0.9891903394d, -0.782318098d, 0.6228791163d, -0.5039610839d, -0.8637263605d, -0.7743120191d, -0.6328039957d,
};
private DistanceFunction distanceFunction = DistanceFunction.EuclideanSq;
private ReturnType returnType = ReturnType.Distance;
private double jitterModifier = 1.0;
private NoiseSampler noiseLookup;
private boolean saltLookup;
public CellularSampler() {
noiseLookup = new OpenSimplex2Sampler();
}
public void setDistanceFunction(DistanceFunction distanceFunction) {
this.distanceFunction = distanceFunction;
}
public void setJitterModifier(double jitterModifier) {
this.jitterModifier = jitterModifier;
}
public void setNoiseLookup(NoiseSampler noiseLookup) {
this.noiseLookup = noiseLookup;
}
public void setReturnType(ReturnType returnType) {
this.returnType = returnType;
}
public void setSaltLookup(boolean saltLookup) {
this.saltLookup = saltLookup;
}
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int xr = (int) Math.round(x);
int yr = (int) Math.round(y);
double distance0 = Double.MAX_VALUE;
double distance1 = Double.MAX_VALUE;
double distance2 = Double.MAX_VALUE;
int closestHash = 0;
double cellularJitter = 0.43701595 * jitterModifier;
int xPrimed = (xr - 1) * PRIME_X;
int yPrimedBase = (yr - 1) * PRIME_Y;
double centerX = x;
double centerY = y;
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int hash = hash(seed, xPrimed, yPrimed);
int idx = hash & (255 << 1);
double vecX = (xi - x) + RAND_VECS_2D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_2D[idx | 1] * cellularJitter;
double newDistance = switch(distanceFunction) {
case Manhattan -> Math.abs(vecX) + Math.abs(vecY);
case Hybrid -> (Math.abs(vecX) + Math.abs(vecY)) + (vecX * vecX + vecY * vecY);
default -> vecX * vecX + vecY * vecY;
};
distance1 = Math.max(Math.min(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_2D[idx | 1] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
distance0 = Math.sqrt(distance0);
if (returnType != ReturnType.Distance) {
distance1 = Math.sqrt(distance1);
}
}
return switch(returnType) {
case CellValue -> closestHash * (1 / 2147483648.0);
case Distance -> distance0 - 1;
case Distance2 -> distance1 - 1;
case Distance2Add -> (distance1 + distance0) * 0.5 - 1;
case Distance2Sub -> distance1 - distance0 - 1;
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
case Distance2Div -> distance0 / distance1 - 1;
case NoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), centerX, centerY);
case LocalNoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), x / frequency - centerX, y / frequency - centerY);
case Distance3 -> distance2 - 1;
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
case Distance3Sub -> distance2 - distance0 - 1;
case Distance3Mul -> distance2 * distance0 - 1;
case Distance3Div -> distance0 / distance2 - 1;
case Angle -> Math.atan2(y / frequency - centerY, x / frequency - centerX);
};
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int xr = (int) Math.round(x);
int yr = (int) Math.round(y);
int zr = (int) Math.round(z);
double distance0 = Double.MAX_VALUE;
double distance1 = Double.MAX_VALUE;
double distance2 = Double.MAX_VALUE;
int closestHash = 0;
double cellularJitter = 0.39614353 * jitterModifier;
int xPrimed = (xr - 1) * PRIME_X;
int yPrimedBase = (yr - 1) * PRIME_Y;
int zPrimedBase = (zr - 1) * PRIME_Z;
double centerX = x;
double centerY = y;
double centerZ = z;
for(int xi = xr - 1; xi <= xr + 1; xi++) {
int yPrimed = yPrimedBase;
for(int yi = yr - 1; yi <= yr + 1; yi++) {
int zPrimed = zPrimedBase;
for(int zi = zr - 1; zi <= zr + 1; zi++) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
int idx = hash & (255 << 2);
double vecX = (xi - x) + RAND_VECS_3D[idx] * cellularJitter;
double vecY = (yi - y) + RAND_VECS_3D[idx | 1] * cellularJitter;
double vecZ = (zi - z) + RAND_VECS_3D[idx | 2] * cellularJitter;
double newDistance = 0;
switch(distanceFunction) {
case Euclidean, EuclideanSq -> newDistance = vecX * vecX + vecY * vecY + vecZ * vecZ;
case Manhattan -> newDistance = Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ);
case Hybrid -> {
newDistance = (Math.abs(vecX) + Math.abs(vecY) + Math.abs(vecZ)) + (vecX * vecX + vecY * vecY + vecZ * vecZ);
distance1 = Math.max(Math.min(distance1, newDistance), distance0);
}
}
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
centerX = ((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
centerY = ((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
centerZ = ((zi + RAND_VECS_3D[idx | 2] * cellularJitter) / frequency);
} else if(newDistance < distance1) {
distance2 = distance1;
distance1 = newDistance;
} else if(newDistance < distance2) {
distance2 = newDistance;
}
zPrimed += PRIME_Z;
}
yPrimed += PRIME_Y;
}
xPrimed += PRIME_X;
}
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
distance0 = Math.sqrt(distance0);
if (returnType != ReturnType.Distance) {
distance1 = Math.sqrt(distance1);
}
}
return switch(returnType) {
case CellValue -> closestHash * (1 / 2147483648.0);
case Distance -> distance0 - 1;
case Distance2 -> distance1 - 1;
case Distance2Add -> (distance1 + distance0) * 0.5 - 1;
case Distance2Sub -> distance1 - distance0 - 1;
case Distance2Mul -> distance1 * distance0 * 0.5 - 1;
case Distance2Div -> distance0 / distance1 - 1;
case NoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), centerX, centerY, centerZ);
case LocalNoiseLookup -> noiseLookup.noise(sl - (saltLookup ? 0 : salt), x / frequency - centerX, y / frequency - centerY,
z / frequency - centerZ);
case Distance3 -> distance2 - 1;
case Distance3Add -> (distance2 + distance0) * 0.5 - 1;
case Distance3Sub -> distance2 - distance0 - 1;
case Distance3Mul -> distance2 * distance0 - 1;
case Distance3Div -> distance0 / distance2 - 1;
case Angle -> Math.atan2(y / frequency - centerY, x / frequency - centerX);
};
}
public enum DistanceFunction {
Euclidean,
EuclideanSq,
Manhattan,
Hybrid
}
public enum ReturnType {
CellValue,
Distance,
Distance2,
Distance2Add,
Distance2Sub,
Distance2Mul,
Distance2Div,
NoiseLookup,
LocalNoiseLookup,
Distance3,
Distance3Add,
Distance3Sub,
Distance3Mul,
Distance3Div,
Angle
}
}
@@ -1,29 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise;
/**
* Sampler3D implementation that returns a constant.
*/
public class ConstantSampler extends NoiseFunction {
private final double constant;
public ConstantSampler(double constant) {
this.constant = constant;
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
return constant;
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
return constant;
}
}
@@ -1,25 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.noise;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
public abstract class DerivativeNoiseFunction extends NoiseFunction implements DerivativeNoiseSampler {
@Override
public boolean isDifferentiable() {
return true;
}
@Override
public double[] noised(long seed, double x, double y) {
return getNoiseDerivativeRaw(seed + salt, x * frequency, y * frequency);
}
@Override
public double[] noised(long seed, double x, double y, double z) {
return getNoiseDerivativeRaw(seed + salt, x * frequency, y * frequency, z * frequency);
}
public abstract double[] getNoiseDerivativeRaw(long seed, double x, double y);
public abstract double[] getNoiseDerivativeRaw(long seed, double x, double y, double z);
}
@@ -1,66 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.noise;
public class DistanceSampler extends NoiseFunction {
private final DistanceFunction distanceFunction;
private final double ox, oy, oz;
private final boolean normalize;
private final double radius;
private final double distanceAtRadius;
public DistanceSampler(DistanceFunction distanceFunction, double ox, double oy, double oz, boolean normalize, double radius) {
frequency = 1;
this.distanceFunction = distanceFunction;
this.ox = ox;
this.oy = oy;
this.oz = oz;
this.normalize = normalize;
this.radius = radius;
this.distanceAtRadius = distance2d(distanceFunction, radius, 0); // distance2d and distance3d should return the same value
}
private static double distance2d(DistanceFunction distanceFunction, double x, double z) {
return switch(distanceFunction) {
case Euclidean -> Math.sqrt(x * x + z * z);
case EuclideanSq -> x * x + z * z;
case Manhattan -> Math.abs(x) + Math.abs(z);
};
}
private static double distance3d(DistanceFunction distanceFunction, double x, double y, double z) {
return switch(distanceFunction) {
case Euclidean -> Math.sqrt(x * x + y * y + z * z);
case EuclideanSq -> x * x + y * y + z * z;
case Manhattan -> Math.abs(x) + Math.abs(y) + Math.abs(z);
};
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
double dx = x - ox;
double dy = y - oz;
if(normalize && (Math.abs(dx) > radius || Math.abs(dy) > radius)) return 1;
double dist = distance2d(distanceFunction, dx, dy);
if(normalize) return Math.min(((2 * dist) / distanceAtRadius) - 1, 1);
return dist;
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
double dx = x - ox;
double dy = y - oy;
double dz = z - oz;
if(normalize && (Math.abs(dx) > radius || Math.abs(dy) > radius || Math.abs(dz) > radius)) return 1;
double dist = distance3d(distanceFunction, dx, dy, dz);
if(normalize) return Math.min(((2 * dist) / distanceAtRadius) - 1, 1);
return dist;
}
public enum DistanceFunction {
Euclidean,
EuclideanSq,
Manhattan
}
}
@@ -1,53 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise;
import com.dfsek.paralithic.Expression;
import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Parser.ParseOptions;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.Function;
import java.util.Map;
import com.dfsek.terra.addons.noise.paralithic.noise.SeedContext;
/**
* NoiseSampler implementation using a Paralithic expression.
*/
public class ExpressionFunction extends NoiseFunction {
private final Expression expression;
public ExpressionFunction(Map<String, Function> functions, String eq, Map<String, Double> vars, ParseOptions parseOptions) throws ParseException {
Parser p = new Parser(parseOptions);
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);
frequency = 1;
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
return expression.evaluate(new SeedContext(seed), x, 0, y);
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
return expression.evaluate(new SeedContext(seed), x, y, z);
}
}
@@ -1,114 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise;
import com.dfsek.terra.addons.noise.samplers.noise.random.WhiteNoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
public class GaborNoiseSampler extends NoiseFunction {
private final WhiteNoiseSampler rand;
private double k = 1.0;
private double a = 0.1;
private double f0 = 0.625;
private double kernelRadius = (Math.sqrt(-Math.log(0.05) / Math.PI) / a);
private double impulsesPerKernel = 64d;
private double impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius));
private double impulsesPerCell = impulseDensity * kernelRadius * kernelRadius;
private double g = Math.exp(-impulsesPerCell);
private double omega0 = Math.PI * 0.25;
private boolean isotropic = true;
public GaborNoiseSampler() {
rand = new WhiteNoiseSampler();
}
private void recalculateRadiusAndDensity() {
kernelRadius = (Math.sqrt(-Math.log(0.05) / Math.PI) / this.a);
impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius));
impulsesPerCell = impulseDensity * kernelRadius * kernelRadius;
g = Math.exp(-impulsesPerCell);
}
private double gaborNoise(long seed, double x, double y) {
x /= kernelRadius;
y /= kernelRadius;
int xi = (int) Math.floor(x);
int yi = (int) Math.floor(y);
double xf = x - xi;
double yf = y - yi;
double noise = 0;
for(int dx = -1; dx <= 1; dx++) {
for(int dz = -1; dz <= 1; dz++) {
noise += calculateCell(seed, xi + dx, yi + dz, xf - dx, yf - dz);
}
}
return noise;
}
private double calculateCell(long seed, int xi, int yi, double x, double y) {
long mashedSeed = MathUtil.murmur64(31L * xi + yi) + seed;
double gaussianSource = (rand.getNoiseRaw(mashedSeed++) + 1) / 2;
int impulses = 0;
while(gaussianSource > g) {
impulses++;
gaussianSource *= (rand.getNoiseRaw(mashedSeed++) + 1) / 2;
}
double noise = 0;
for(int i = 0; i < impulses; i++) {
noise += rand.getNoiseRaw(mashedSeed++) * gabor(isotropic ? (rand.getNoiseRaw(mashedSeed++) + 1) * Math.PI : omega0,
x * kernelRadius, y * kernelRadius);
}
return noise;
}
private double gabor(double omega_0, double x, double y) {
return k * (Math.exp(-Math.PI * (a * a) * (x * x + y * y)) * MathUtil.cos(2 * Math.PI * f0 * (x * MathUtil.cos(omega_0) +
y * MathUtil.sin(
omega_0))));
}
public void setA(double a) {
this.a = a;
recalculateRadiusAndDensity();
}
public void setDeviation(double k) {
this.k = k;
}
public void setFrequency0(double f0) {
this.f0 = f0;
}
public void setImpulsesPerKernel(double impulsesPerKernel) {
this.impulsesPerKernel = impulsesPerKernel;
recalculateRadiusAndDensity();
}
public void setIsotropic(boolean isotropic) {
this.isotropic = isotropic;
}
public void setRotation(double omega0) {
this.omega0 = Math.PI * omega0;
}
@Override
public double getNoiseRaw(long seed, double x, double z) {
return gaborNoise(seed, x, z);
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
return gaborNoise(seed, x, z);
}
}
@@ -1,65 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise;
import com.dfsek.terra.api.noise.NoiseSampler;
public abstract class NoiseFunction implements NoiseSampler {
// Hashing
protected static final int PRIME_X = 501125321;
protected static final int PRIME_Y = 1136930381;
protected static final int PRIME_Z = 1720413743;
protected double frequency = 0.02d;
protected long salt;
public NoiseFunction() {
this.salt = 0;
}
protected static int hash(int seed, int xPrimed, int yPrimed, int zPrimed) {
int hash = seed ^ xPrimed ^ yPrimed ^ zPrimed;
hash *= 0x27d4eb2d;
return hash;
}
protected static int hash(int seed, int xPrimed, int yPrimed) {
int hash = seed ^ xPrimed ^ yPrimed;
hash *= 0x27d4eb2d;
return hash;
}
public void setSalt(long salt) {
this.salt = salt;
}
public double getFrequency() {
return frequency;
}
public void setFrequency(double frequency) {
this.frequency = frequency;
}
@Override
public double noise(long seed, double x, double y) {
return getNoiseRaw(seed + salt, x * frequency, y * frequency);
}
@Override
public double noise(long seed, double x, double y, double z) {
return getNoiseRaw(seed + salt, x * frequency, y * frequency, z * frequency);
}
public abstract double getNoiseRaw(long seed, double x, double y);
public abstract double getNoiseRaw(long seed, double x, double y, double z);
}
@@ -1,173 +0,0 @@
package com.dfsek.terra.addons.noise.samplers.noise;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
public class PseudoErosionSampler extends NoiseFunction {
public static final double TAU = 2.0 * Math.PI;
private static final double HASH_X = 0.3183099f;
private static final double HASH_Y = 0.3678794f;
public final double gain;
public final double lacunarity;
public final double slopeStrength;
public final double branchStrength;
public final double erosionStrength;
private final int octaves;
private final double erosionFrequency;
private final DerivativeNoiseSampler sampler;
private final boolean slopeMask;
private final double slopeMaskFullSq;
private final double slopeMaskNoneSq;
private final double jitter;
private final double maxCellDistSq;
private final double maxCellDistSqRecip;
private final boolean averageErosionImpulses;
public PseudoErosionSampler(int octaves, double gain, double lacunarity, double slopeStrength, double branchStrength,
double erosionStrength, double erosionFrequency, DerivativeNoiseSampler sampler,
boolean slopeMask, double slopeMaskFull, double slopeMaskNone, double jitterModifier,
boolean averageErosionImpulses) {
this.octaves = octaves;
this.gain = gain;
this.lacunarity = lacunarity;
this.slopeStrength = slopeStrength;
this.branchStrength = branchStrength;
this.erosionStrength = erosionStrength;
this.erosionFrequency = erosionFrequency;
this.sampler = sampler;
this.slopeMask = slopeMask;
// Square these values and maintain sign since they're compared to a
// squared value, otherwise a sqrt would need to be used
this.slopeMaskFullSq = slopeMaskFull * slopeMaskFull * Math.signum(slopeMaskFull);
this.slopeMaskNoneSq = slopeMaskNone * slopeMaskNone * Math.signum((slopeMaskNone));
this.jitter = 0.43701595 * jitterModifier;
this.averageErosionImpulses = averageErosionImpulses;
this.maxCellDistSq = 1 + jitter * jitter;
this.maxCellDistSqRecip = 1 / maxCellDistSq;
}
public static double hashX(double seed, double n) {
// Swapped the components here
double nx = HASH_X * n * seed;
return -1.0f + 2.0f * fract(nx);
}
public static double hashY(double seed, double n) {
double ny = HASH_Y * n * seed;
return -1.0f + 2.0f * fract(ny);
}
public static double fract(double x) {
return (x - Math.floor(x));
}
public static double smoothstep(double edge0, double edge1, double x) {
// Scale, bias and saturate x to 0..1 range
x = clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
// Evaluate polynomial
return x * x * (3 - 2 * x);
}
public static double clamp(double x, double minVal, double maxVal) {
return Math.max(minVal, Math.min(maxVal, x));
}
public static double dot(double x1, double y1, double x2, double y2) {
return x1 * x2 + y1 * y2;
}
public double[] erosion(int seed, double x, double y, double dirX, double dirY) {
int gridX = (int) Math.round(x);
int gridY = (int) Math.round(y);
double noise = 0.0f;
double dirOutX = 0.0f;
double dirOutY = 0.0f;
double cumAmp = 0.0f;
for(int cellX = gridX - 1; cellX <= gridX + 1; cellX++) {
for(int cellY = gridY - 1; cellY <= gridY + 1; cellY++) {
double cellHash = hash(seed, cellX, cellY);
double cellOffsetX = hashX(seed, cellHash) * jitter;
double cellOffsetY = hashY(seed, cellHash) * jitter;
double cellOriginDeltaX = (x - cellX) + cellOffsetX;
double cellOriginDeltaY = (y - cellY) + cellOffsetY;
double cellOriginDistSq = cellOriginDeltaX * cellOriginDeltaX + cellOriginDeltaY * cellOriginDeltaY;
if(cellOriginDistSq > maxCellDistSq) continue; // Skip calculating cells too far away
double ampTmp = (cellOriginDistSq * maxCellDistSqRecip) - 1;
double amp = ampTmp * ampTmp; // Decrease cell amplitude further away
cumAmp += amp;
double directionalStrength = dot(cellOriginDeltaX, cellOriginDeltaY, dirX, dirY) * TAU;
noise += MathUtil.cos(directionalStrength) * amp;
double sinAngle = MathUtil.sin(directionalStrength) * amp;
dirOutX -= sinAngle * (cellOriginDeltaX + dirX);
dirOutY -= sinAngle * (cellOriginDeltaY + dirY);
}
}
if(averageErosionImpulses && cumAmp != 0) {
noise /= cumAmp;
dirOutX /= cumAmp;
dirOutY /= cumAmp;
}
return new double[]{ noise, dirOutX, dirOutY };
}
public double heightMap(long seed, double x, double y) {
double[] sample = sampler.noised(seed, x, y);
double height = sample[0];
double heightDirX = sample[1];
double heightDirY = sample[2];
// Take the curl of the normal to get the gradient facing down the slope
double baseDirX = heightDirY * slopeStrength;
double baseDirY = -heightDirX * slopeStrength;
double erosion = 0.0f;
double dirX = 0.0f;
double dirY = 0.0f;
double amp = 1.0f;
double cumAmp = 0.0f;
double freq = 1.0f;
// Stack erosion octaves
for(int i = 0; i < octaves; i++) {
double[] erosionResult = erosion((int) seed,
x * freq * erosionFrequency,
y * freq * erosionFrequency,
baseDirX + dirY * branchStrength,
baseDirY - dirX * branchStrength);
erosion += erosionResult[0] * amp;
dirX += erosionResult[1] * amp * freq;
dirY += erosionResult[2] * amp * freq;
cumAmp += amp;
amp *= gain;
freq *= lacunarity;
}
// Normalize erosion noise
erosion /= cumAmp;
// [-1, 1] -> [0, 1]
erosion = erosion * 0.5F + 0.5F;
// Without masking, erosion noise in areas with small gradients tend to produce mounds,
// this reduces erosion amplitude towards smaller gradients to avoid this
if(slopeMask) {
double dirMagSq = dot(baseDirX, baseDirY, baseDirX, baseDirY);
double flatness = smoothstep((double) slopeMaskNoneSq, slopeMaskFullSq, dirMagSq);
erosion *= flatness;
}
return height + erosion * erosionStrength;
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
return heightMap(seed, x, y);
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
return getNoiseRaw(seed, x, z);
}
}
@@ -1,112 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.fractal;
import com.dfsek.terra.api.noise.DerivativeNoiseSampler;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
public class BrownianMotionSampler extends FractalNoiseFunction {
public BrownianMotionSampler(NoiseSampler input) {
super(input);
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = input.noise(seed++, x, y);
sum += noise * amp;
amp *= MathUtil.lerp(weightedStrength, 1.0, Math.min(noise + 1, 2) * 0.5);
x *= lacunarity;
y *= lacunarity;
amp *= gain;
}
return sum;
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = input.noise(seed++, x, y, z);
sum += noise * amp;
amp *= MathUtil.lerp(weightedStrength, 1.0, (noise + 1) * 0.5);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
@Override
public boolean isDifferentiable() {
return DerivativeNoiseSampler.isDifferentiable(input);
}
@Override
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
double[] sum = {0, 0, 0};
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
// This should only be called after `input` is verified as a `DerivativeNoiseSampler`
// so this should be a safe cast
double[] noise = ((DerivativeNoiseSampler) input).noised(seed++, x, y);
sum[0] += noise[0] * amp;
// Directional derivative of each octave can be subject to the same addition and product
// as per derivative sum and product rules in order to produce the correct final derivative
sum[1] += noise[1] * amp;
sum[2] += noise[2] * amp;
amp *= MathUtil.lerp(weightedStrength, 1.0, Math.min(noise[0] + 1, 2) * 0.5);
x *= lacunarity;
y *= lacunarity;
amp *= gain;
}
return sum;
}
@Override
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
double[] sum = {0, 0, 0, 0};
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double[] noise = ((DerivativeNoiseSampler) input).noised(seed++, x, y, z);
sum[0] += noise[0] * amp;
// See comment in 2D version
sum[1] += noise[1] * amp;
sum[2] += noise[2] * amp;
sum[3] += noise[3] * amp;
amp *= MathUtil.lerp(weightedStrength, 1.0, (noise[0] + 1) * 0.5);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
}
@@ -1,70 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.fractal;
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
import com.dfsek.terra.api.noise.NoiseSampler;
public abstract class FractalNoiseFunction extends DerivativeNoiseFunction {
protected final NoiseSampler input;
protected double fractalBounding = 1 / 1.75;
protected int octaves = 3;
protected double gain = 0.5;
protected double lacunarity = 2.0d;
protected double weightedStrength = 0.0d;
public FractalNoiseFunction(NoiseSampler input) {
this.input = input;
frequency = 1;
}
protected void calculateFractalBounding() {
double gain = Math.abs(this.gain);
double amp = gain;
double ampFractal = 1.0;
for(int i = 1; i < octaves; i++) {
ampFractal += amp;
amp *= gain;
}
fractalBounding = 1 / ampFractal;
}
public void setGain(double gain) {
this.gain = gain;
calculateFractalBounding();
}
public void setLacunarity(double lacunarity) {
this.lacunarity = lacunarity;
}
public void setOctaves(int octaves) {
this.octaves = octaves;
calculateFractalBounding();
}
public void setWeightedStrength(double weightedStrength) {
this.weightedStrength = weightedStrength;
}
@Override
public boolean isDifferentiable() {
return false;
}
@Override
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
}
@Override
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
}
}
@@ -1,67 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.fractal;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
public class PingPongSampler extends FractalNoiseFunction {
private double pingPongStrength = 2.0;
public PingPongSampler(NoiseSampler input) {
super(input);
}
private static double pingPong(double t) {
t -= (int) (t * 0.5f) << 1;
return t < 1 ? t : 2 - t;
}
public void setPingPongStrength(double strength) {
this.pingPongStrength = strength;
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = pingPong((input.noise(seed++, x, y) + 1) * pingPongStrength);
sum += (noise - 0.5) * 2 * amp;
amp *= MathUtil.lerp(weightedStrength, 1.0, noise);
x *= lacunarity;
y *= lacunarity;
amp *= gain;
}
return sum;
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = pingPong((input.noise(seed++, x, y, z) + 1) * pingPongStrength);
sum += (noise - 0.5) * 2 * amp;
amp *= MathUtil.lerp(weightedStrength, 1.0, noise);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
}
@@ -1,56 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.fractal;
import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.MathUtil;
public class RidgedFractalSampler extends FractalNoiseFunction {
public RidgedFractalSampler(NoiseSampler input) {
super(input);
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = Math.abs(input.noise(seed++, x, y));
sum += (noise * -2 + 1) * amp;
amp *= MathUtil.lerp(weightedStrength, 1.0, 1 - noise);
x *= lacunarity;
y *= lacunarity;
amp *= gain;
}
return sum;
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
double sum = 0;
double amp = fractalBounding;
for(int i = 0; i < octaves; i++) {
double noise = Math.abs(input.noise(seed++, x, y, z));
sum += (noise * -2 + 1) * amp;
amp *= MathUtil.lerp(weightedStrength, 1.0, 1 - noise);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
}
@@ -1,46 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.random;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
/**
* NoiseSampler implementation to provide random, normally distributed (Gaussian) noise.
*/
public class GaussianNoiseSampler extends NoiseFunction {
private final WhiteNoiseSampler whiteNoiseSampler; // Back with a white noise sampler.
public GaussianNoiseSampler() {
whiteNoiseSampler = new WhiteNoiseSampler();
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
double v1, v2, s;
do {
v1 = whiteNoiseSampler.noise(seed++, x, y);
v2 = whiteNoiseSampler.noise(seed++, x, y);
s = v1 * v1 + v2 * v2;
} while(s >= 1 || s == 0);
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
return v1 * multiplier;
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
double v1, v2, s;
do {
v1 = whiteNoiseSampler.noise(seed++, x, y, z);
v2 = whiteNoiseSampler.noise(seed++, x, y, z);
s = v1 * v1 + v2 * v2;
} while(s >= 1 || s == 0);
double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s) / s);
return v1 * multiplier;
}
}
@@ -1,33 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.random;
import com.dfsek.terra.api.util.MathUtil;
/**
* NoiseSampler implementation to produce random, uniformly distributed (white) noise.
*/
public class PositiveWhiteNoiseSampler extends WhiteNoiseSampler {
private static final long POSITIVE_POW1 = 0b01111111111L << 52;
// Bits that when applied to the exponent/sign section of a double, produce a positive number with a power of 1.
public double getNoiseRaw(long seed) {
return (Double.longBitsToDouble((MathUtil.murmur64(seed) & 0x000fffffffffffffL) | POSITIVE_POW1) - 1.5) * 2;
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
return (getNoiseUnmapped(seed, x, y) - 1);
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
return (getNoiseUnmapped(seed, x, y, z) - 1);
}
}
@@ -1,61 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.random;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
import com.dfsek.terra.api.util.MathUtil;
/**
* NoiseSampler implementation to produce random, uniformly distributed (white) noise.
*/
public class WhiteNoiseSampler extends NoiseFunction {
private static final long POSITIVE_POW1 = 0b01111111111L << 52;
// Bits that when applied to the exponent/sign section of a double, produce a positive number with a power of 1.
public WhiteNoiseSampler() {
}
public long randomBits(long seed, double x, double y, double z) {
long hashX = Double.doubleToRawLongBits(x) ^ seed;
long hashZ = Double.doubleToRawLongBits(y) ^ seed;
long hash = (((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed) + Double.doubleToRawLongBits(z);
return MathUtil.murmur64(hash);
}
public long randomBits(long seed, double x, double y) {
long hashX = Double.doubleToRawLongBits(x) ^ seed;
long hashZ = Double.doubleToRawLongBits(y) ^ seed;
long hash = ((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed;
return MathUtil.murmur64(hash);
}
public double getNoiseRaw(long seed) {
return (Double.longBitsToDouble((MathUtil.murmur64(seed) & 0x000fffffffffffffL) | POSITIVE_POW1) - 1.5) * 2;
}
@Override
public double getNoiseRaw(long seed, double x, double y) {
return (getNoiseUnmapped(seed, x, y) - 1.5) * 2;
}
@Override
public double getNoiseRaw(long seed, double x, double y, double z) {
return (getNoiseUnmapped(seed, x, y, z) - 1.5) * 2;
}
public double getNoiseUnmapped(long seed, double x, double y, double z) {
long base = ((randomBits(seed, x, y, z)) & 0x000fffffffffffffL) | POSITIVE_POW1; // Sign and exponent
return Double.longBitsToDouble(base);
}
public double getNoiseUnmapped(long seed, double x, double y) {
long base = (randomBits(seed, x, y) & 0x000fffffffffffffL) | POSITIVE_POW1; // Sign and exponent
return Double.longBitsToDouble(base);
}
}
@@ -1,699 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.simplex;
/**
* NoiseSampler implementation to provide OpenSimplex2 (Smooth Variant) noise.
*/
public class OpenSimplex2SSampler extends SimplexStyleSampler {
@Override
@SuppressWarnings("NumericOverflow")
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
// 2D OpenSimplex2S case is a modified 2D simplex noise.
final double SQRT3 = 1.7320508075688772935274463415059;
final double G2 = (3 - SQRT3) / 6;
final double F2 = 0.5f * (SQRT3 - 1);
double s = (x + y) * F2;
x += s;
y += s;
int i = (int) Math.floor(x);
int j = (int) Math.floor(y);
double xi = x - i;
double yi = y - j;
i *= PRIME_X;
j *= PRIME_Y;
int i1 = i + PRIME_X;
int j1 = j + PRIME_Y;
double t = (xi + yi) * G2;
double x0 = xi - t;
double y0 = yi - t;
double a0 = (2.0 / 3.0) - x0 * x0 - y0 * y0;
double value = (a0 * a0) * (a0 * a0) * gradCoord(seed, i, j, x0, y0);
double a1 = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0);
double x1 = x0 - (1 - 2 * G2);
double y1 = y0 - (1 - 2 * G2);
value += (a1 * a1) * (a1 * a1) * gradCoord(seed, i1, j1, x1, y1);
// Nested conditionals were faster than compact bit logic/arithmetic.
double xmyi = xi - yi;
if(t > G2) {
if(xi + xmyi > 1) {
double x2 = x0 + (3 * G2 - 2);
double y2 = y0 + (3 * G2 - 1);
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i + (PRIME_X << 1), j + PRIME_Y, x2, y2);
}
} else {
double x2 = x0 + G2;
double y2 = y0 + (G2 - 1);
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i, j + PRIME_Y, x2, y2);
}
}
if(yi - xmyi > 1) {
double x3 = x0 + (3 * G2 - 1);
double y3 = y0 + (3 * G2 - 2);
double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3;
if(a3 > 0) {
value += (a3 * a3) * (a3 * a3) * gradCoord(seed, i + PRIME_X, j + (PRIME_Y << 1), x3, y3);
}
} else {
double x3 = x0 + (G2 - 1);
double y3 = y0 + G2;
double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3;
if(a3 > 0) {
value += (a3 * a3) * (a3 * a3) * gradCoord(seed, i + PRIME_X, j, x3, y3);
}
}
} else {
if(xi + xmyi < 0) {
double x2 = x0 + (1 - G2);
double y2 = y0 - G2;
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i - PRIME_X, j, x2, y2);
}
} else {
double x2 = x0 + (G2 - 1);
double y2 = y0 + G2;
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i + PRIME_X, j, x2, y2);
}
}
if(yi < xmyi) {
double x2 = x0 - G2;
double y2 = y0 - (G2 - 1);
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i, j - PRIME_Y, x2, y2);
}
} else {
double x2 = x0 + G2;
double y2 = y0 + (G2 - 1);
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i, j + PRIME_Y, x2, y2);
}
}
}
return value * 18.24196194486065;
}
@Override
@SuppressWarnings("NumericOverflow")
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
// 3D OpenSimplex2S case uses two offset rotated cube grids.
final double R3 = (2.0 / 3.0);
double r = (x + y + z) * R3; // Rotation, not skew
x = r - x;
y = r - y;
z = r - z;
int i = (int) Math.floor(x);
int j = (int) Math.floor(y);
int k = (int) Math.floor(z);
double xi = x - i;
double yi = y - j;
double zi = z - k;
i *= PRIME_X;
j *= PRIME_Y;
k *= PRIME_Z;
int seed2 = seed + 1293373;
int xNMask = (int) (-0.5 - xi);
int yNMask = (int) (-0.5 - yi);
int zNMask = (int) (-0.5 - zi);
double x0 = xi + xNMask;
double y0 = yi + yNMask;
double z0 = zi + zNMask;
double a0 = 0.75 - x0 * x0 - y0 * y0 - z0 * z0;
double value = (a0 * a0) * (a0 * a0) * gradCoord(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z), x0,
y0,
z0);
double x1 = xi - 0.5;
double y1 = yi - 0.5;
double z1 = zi - 0.5;
double a1 = 0.75 - x1 * x1 - y1 * y1 - z1 * z1;
value += (a1 * a1) * (a1 * a1) * gradCoord(seed2, i + PRIME_X, j + PRIME_Y, k + PRIME_Z, x1, y1, z1);
double xAFlipMask0 = ((xNMask | 1) << 1) * x1;
double yAFlipMask0 = ((yNMask | 1) << 1) * y1;
double zAFlipMask0 = ((zNMask | 1) << 1) * z1;
double xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0;
double yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0;
double zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0;
boolean skip5 = false;
double a2 = xAFlipMask0 + a0;
if(a2 > 0) {
double x2 = x0 - (xNMask | 1);
value += (a2 * a2) * (a2 * a2) * gradCoord(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z), x2,
y0,
z0);
} else {
double a3 = yAFlipMask0 + zAFlipMask0 + a0;
if(a3 > 0) {
double y3 = y0 - (yNMask | 1);
double z3 = z0 - (zNMask | 1);
value += (a3 * a3) * (a3 * a3) * gradCoord(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (~zNMask & PRIME_Z),
x0,
y3, z3);
}
double a4 = xAFlipMask1 + a1;
if(a4 > 0) {
double x4 = (xNMask | 1) + x1;
value += (a4 * a4) * (a4 * a4) * gradCoord(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + PRIME_Z, x4, y1, z1);
skip5 = true;
}
}
boolean skip9 = false;
double a6 = yAFlipMask0 + a0;
if(a6 > 0) {
double y6 = y0 - (yNMask | 1);
value += (a6 * a6) * (a6 * a6) * gradCoord(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z), x0,
y6,
z0);
} else {
double a7 = xAFlipMask0 + zAFlipMask0 + a0;
if(a7 > 0) {
double x7 = x0 - (xNMask | 1);
double z7 = z0 - (zNMask | 1);
value += (a7 * a7) * (a7 * a7) * gradCoord(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z),
x7,
y0, z7);
}
double a8 = yAFlipMask1 + a1;
if(a8 > 0) {
double y8 = (yNMask | 1) + y1;
value += (a8 * a8) * (a8 * a8) * gradCoord(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z, x1, y8, z1);
skip9 = true;
}
}
boolean skipD = false;
double aA = zAFlipMask0 + a0;
if(aA > 0) {
double zA = z0 - (zNMask | 1);
value += (aA * aA) * (aA * aA) * gradCoord(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z), x0,
y0,
zA);
} else {
double aB = xAFlipMask0 + yAFlipMask0 + a0;
if(aB > 0) {
double xB = x0 - (xNMask | 1);
double yB = y0 - (yNMask | 1);
value += (aB * aB) * (aB * aB) * gradCoord(seed, i + (~xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z),
xB,
yB, z0);
}
double aC = zAFlipMask1 + a1;
if(aC > 0) {
double zC = (zNMask | 1) + z1;
value += (aC * aC) * (aC * aC) * gradCoord(seed2, i + PRIME_X, j + PRIME_Y, k + (zNMask & (PRIME_Z << 1)), x1, y1, zC);
skipD = true;
}
}
if(!skip5) {
double a5 = yAFlipMask1 + zAFlipMask1 + a1;
if(a5 > 0) {
double y5 = (yNMask | 1) + y1;
double z5 = (zNMask | 1) + z1;
value += (a5 * a5) * (a5 * a5) * gradCoord(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + (zNMask & (PRIME_Z << 1)),
x1, y5, z5);
}
}
if(!skip9) {
double a9 = xAFlipMask1 + zAFlipMask1 + a1;
if(a9 > 0) {
double x9 = (xNMask | 1) + x1;
double z9 = (zNMask | 1) + z1;
value += (a9 * a9) * (a9 * a9) * gradCoord(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + (zNMask & (PRIME_Z << 1)),
x9,
y1, z9);
}
}
if(!skipD) {
double aD = xAFlipMask1 + yAFlipMask1 + a1;
if(aD > 0) {
double xD = (xNMask | 1) + x1;
double yD = (yNMask | 1) + y1;
value += (aD * aD) * (aD * aD) * gradCoord(seed2, i + (xNMask & (PRIME_X << 1)), j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z,
xD, yD, z1);
}
}
return value * 9.046026385208288;
}
@Override
public boolean isDifferentiable() {
return true;
}
@Override
public double[] getNoiseDerivativeRaw(long sl, double x, double y) {
int seed = (int) sl;
// 2D OpenSimplex2S case is a modified 2D simplex noise.
final double SQRT3 = 1.7320508075688772935274463415059;
final double G2 = (3 - SQRT3) / 6;
final double F2 = 0.5f * (SQRT3 - 1);
double s = (x + y) * F2;
x += s;
y += s;
int i = (int) Math.floor(x);
int j = (int) Math.floor(y);
double xi = x - i;
double yi = y - j;
i *= PRIME_X;
j *= PRIME_Y;
int i1 = i + PRIME_X;
int j1 = j + PRIME_Y;
double t = (xi + yi) * G2;
double x0 = xi - t;
double y0 = yi - t;
double[] out = { 0.0f, 0.0f, 0.0f };
double a0 = (2.0 / 3.0) - x0 * x0 - y0 * y0;
double aa0 = a0 * a0, aaa0 = aa0 * a0, aaaa0 = aa0 * aa0;
int gi0 = gradCoordIndex(seed, i, j);
double gx0 = GRADIENTS_2_D[gi0], gy0 = GRADIENTS_2_D[gi0 | 1];
double rampValue0 = gx0 * x0 + gy0 * y0;
out[0] = aaaa0 * rampValue0;
out[1] = gx0 * aaaa0 - 8 * rampValue0 * aaa0 * x0;
out[2] = gy0 * aaaa0 - 8 * rampValue0 * aaa0 * y0;
double a1 = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a0);
double x1 = x0 - (1 - 2 * G2);
double y1 = y0 - (1 - 2 * G2);
double aa1 = a1 * a1, aaa1 = aa1 * a1, aaaa1 = aa1 * aa1;
int gi1 = gradCoordIndex(seed, i1, j1);
double gx1 = GRADIENTS_2_D[gi1], gy1 = GRADIENTS_2_D[gi1 | 1];
double rampValue1 = gx1 * x1 + gy1 * y1;
out[0] += aaaa1 * rampValue1;
out[1] += gx1 * aaaa1 - 8 * rampValue1 * aaa1 * x1;
out[2] += gy1 * aaaa1 - 8 * rampValue1 * aaa1 * y1;
// Nested conditionals were faster than compact bit logic/arithmetic.
double xmyi = xi - yi;
if(t > G2) {
if(xi + xmyi > 1) {
double x2 = x0 + (3 * G2 - 2);
double y2 = y0 + (3 * G2 - 1);
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
int gi2 = gradCoordIndex(seed, i + (PRIME_X << 1), j + PRIME_Y);
double gx2 = GRADIENTS_2_D[gi2 | 0], gy2 = GRADIENTS_2_D[gi2 | 1];
double rampValue2 = gx2 * x2 + gy2 * y2;
out[0] += aaaa2 * rampValue2;
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
}
} else {
double x2 = x0 + G2;
double y2 = y0 + (G2 - 1);
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
int gi2 = gradCoordIndex(seed, i, j + PRIME_Y);
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
double rampValue2 = gx2 * x2 + gy2 * y2;
out[0] += aaaa2 * rampValue2;
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
}
}
if(yi - xmyi > 1) {
double x3 = x0 + (3 * G2 - 1);
double y3 = y0 + (3 * G2 - 2);
double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3;
if(a3 > 0) {
double aa3 = a3 * a3, aaa3 = aa3 * a3, aaaa3 = aa3 * aa3;
int gi3 = gradCoordIndex(seed, i + PRIME_X, j + (PRIME_Y << 1));
double gx3 = GRADIENTS_2_D[gi3], gy3 = GRADIENTS_2_D[gi3 | 1];
double rampValue3 = gx3 * x3 + gy3 * y3;
out[0] += aaaa3 * rampValue3;
out[1] += gx3 * aaaa3 - 8 * rampValue3 * aaa3 * x3;
out[2] += gy3 * aaaa3 - 8 * rampValue3 * aaa3 * y3;
}
} else {
double x3 = x0 + (G2 - 1);
double y3 = y0 + G2;
double a3 = (2.0 / 3.0) - x3 * x3 - y3 * y3;
if(a3 > 0) {
double aa3 = a3 * a3, aaa3 = aa3 * a3, aaaa3 = aa3 * aa3;
int gi3 = gradCoordIndex(seed, i + PRIME_X, j);
double gx3 = GRADIENTS_2_D[gi3], gy3 = GRADIENTS_2_D[gi3 | 1];
double rampValue3 = gx3 * x3 + gy3 * y3;
out[0] += aaaa3 * rampValue3;
out[1] += gx3 * aaaa3 - 8 * rampValue3 * aaa3 * x3;
out[2] += gy3 * aaaa3 - 8 * rampValue3 * aaa3 * y3;
}
}
} else {
if(xi + xmyi < 0) {
double x2 = x0 + (1 - G2);
double y2 = y0 - G2;
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
int gi2 = gradCoordIndex(seed, i - PRIME_X, j);
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
double rampValue2 = gx2 * x2 + gy2 * y2;
out[0] += aaaa2 * rampValue2;
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
}
} else {
double x2 = x0 + (G2 - 1);
double y2 = y0 + G2;
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
int gi2 = gradCoordIndex(seed, i + PRIME_X, j);
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
double rampValue2 = gx2 * x2 + gy2 * y2;
out[0] += aaaa2 * rampValue2;
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
}
}
if(yi < xmyi) {
double x2 = x0 - G2;
double y2 = y0 - (G2 - 1);
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
int gi2 = gradCoordIndex(seed, i, j - PRIME_Y);
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
double rampValue2 = gx2 * x2 + gy2 * y2;
out[0] += aaaa2 * rampValue2;
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
}
} else {
double x2 = x0 + G2;
double y2 = y0 + (G2 - 1);
double a2 = (2.0 / 3.0) - x2 * x2 - y2 * y2;
if(a2 > 0) {
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
int gi2 = gradCoordIndex(seed, i, j + PRIME_Y);
double gx2 = GRADIENTS_2_D[gi2], gy2 = GRADIENTS_2_D[gi2 | 1];
double rampValue2 = gx2 * x2 + gy2 * y2;
out[0] += aaaa2 * rampValue2;
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y2;
}
}
}
out[0] *= 18.24196194486065;
out[1] *= 18.24196194486065;
out[2] *= 18.24196194486065;
return out;
}
@Override
public double[] getNoiseDerivativeRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
// 3D OpenSimplex2S case uses two offset rotated cube grids.
final double R3 = (2.0 / 3.0);
double r = (x + y + z) * R3; // Rotation, not skew
x = r - x;
y = r - y;
z = r - z;
int i = (int) Math.floor(x);
int j = (int) Math.floor(y);
int k = (int) Math.floor(z);
double xi = x - i;
double yi = y - j;
double zi = z - k;
i *= PRIME_X;
j *= PRIME_Y;
k *= PRIME_Z;
int seed2 = seed + 1293373;
int xNMask = (int) (-0.5 - xi);
int yNMask = (int) (-0.5 - yi);
int zNMask = (int) (-0.5 - zi);
double[] out = { 0.0f, 0.0f, 0.0f, 0.0f };
double x0 = xi + xNMask;
double y0 = yi + yNMask;
double z0 = zi + zNMask;
double a0 = 0.75 - x0 * x0 - y0 * y0 - z0 * z0;
double aa0 = a0 * a0, aaa0 = aa0 * a0, aaaa0 = aa0 * aa0;
int gi0 = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z));
double gx0 = GRADIENTS_3D[gi0], gy0 = GRADIENTS_3D[gi0 | 1], gz0 = GRADIENTS_3D[gi0 | 2];
double rampValue0 = gx0 * x0 + gy0 * y0 + gz0 * z0;
out[0] = aaaa0 * rampValue0;
out[1] = gx0 * aaaa0 - 8 * rampValue0 * aaa0 * x0;
out[2] = gy0 * aaaa0 - 8 * rampValue0 * aaa0 * y0;
out[3] = gz0 * aaaa0 - 8 * rampValue0 * aaa0 * z0;
double x1 = xi - 0.5;
double y1 = yi - 0.5;
double z1 = zi - 0.5;
double a1 = 0.75 - x1 * x1 - y1 * y1 - z1 * z1;
double aa1 = a1 * a1, aaa1 = aa1 * a1, aaaa1 = aa1 * aa1;
int gi1 = gradCoordIndex(seed2, i + PRIME_X, j + PRIME_Y, k + PRIME_Z);
double gx1 = GRADIENTS_3D[gi1], gy1 = GRADIENTS_3D[gi1 | 1], gz1 = GRADIENTS_3D[gi1 | 2];
double rampValue1 = gx1 * x1 + gy1 * y1 + gz1 * z1;
out[0] += aaaa1 * rampValue1;
out[1] += gx1 * aaaa1 - 8 * rampValue1 * aaa1 * x1;
out[2] += gy1 * aaaa1 - 8 * rampValue1 * aaa1 * y1;
out[3] += gz1 * aaaa1 - 8 * rampValue1 * aaa1 * z1;
double xAFlipMask0 = ((xNMask | 1) << 1) * x1;
double yAFlipMask0 = ((yNMask | 1) << 1) * y1;
double zAFlipMask0 = ((zNMask | 1) << 1) * z1;
double xAFlipMask1 = (-2 - (xNMask << 2)) * x1 - 1.0;
double yAFlipMask1 = (-2 - (yNMask << 2)) * y1 - 1.0;
double zAFlipMask1 = (-2 - (zNMask << 2)) * z1 - 1.0;
boolean skip5 = false;
double a2 = xAFlipMask0 + a0;
if(a2 > 0) {
double x2 = x0 - (xNMask | 1);
double aa2 = a2 * a2, aaa2 = aa2 * a2, aaaa2 = aa2 * aa2;
int gi2 = gradCoordIndex(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (zNMask & PRIME_Z));
double gx2 = GRADIENTS_3D[gi2], gy2 = GRADIENTS_3D[gi2 | 1], gz2 = GRADIENTS_3D[gi2 | 2];
double rampValue2 = gx2 * x2 + gy2 * y0 + gz2 * z0;
out[0] += aaaa2 * rampValue2;
out[1] += gx2 * aaaa2 - 8 * rampValue2 * aaa2 * x2;
out[2] += gy2 * aaaa2 - 8 * rampValue2 * aaa2 * y0;
out[3] += gz2 * aaaa2 - 8 * rampValue2 * aaa2 * z0;
} else {
double a3 = yAFlipMask0 + zAFlipMask0 + a0;
if(a3 > 0) {
double y3 = y0 - (yNMask | 1);
double z3 = z0 - (zNMask | 1);
double aa3 = a3 * a3, aaa3 = aa3 * a3, aaaa3 = aa3 * aa3;
int gi3 = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (~zNMask & PRIME_Z));
double gx3 = GRADIENTS_3D[gi3], gy3 = GRADIENTS_3D[gi3 | 1], gz3 = GRADIENTS_3D[gi3 | 2];
double rampValue3 = gx3 * x0 + gy3 * y3 + gz3 * z3;
out[0] += aaaa3 * rampValue3;
out[1] += gx3 * aaaa3 - 8 * rampValue3 * aaa3 * x0;
out[2] += gy3 * aaaa3 - 8 * rampValue3 * aaa3 * y3;
out[3] += gz3 * aaaa3 - 8 * rampValue3 * aaa3 * z3;
}
double a4 = xAFlipMask1 + a1;
if(a4 > 0) {
double x4 = (xNMask | 1) + x1;
double aa4 = a4 * a4, aaa4 = aa4 * a4, aaaa4 = aa4 * aa4;
int gi4 = gradCoordIndex(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + PRIME_Z);
double gx4 = GRADIENTS_3D[gi4], gy4 = GRADIENTS_3D[gi4 | 1], gz4 = GRADIENTS_3D[gi4 | 2];
double rampValue4 = gx4 * x4 + gy4 * y1 + gz4 * z1;
out[0] += aaaa4 * rampValue4;
out[1] += gx4 * aaaa4 - 8 * rampValue4 * aaa4 * x4;
out[2] += gy4 * aaaa4 - 8 * rampValue4 * aaa4 * y1;
out[3] += gz4 * aaaa4 - 8 * rampValue4 * aaa4 * z1;
skip5 = true;
}
}
boolean skip9 = false;
double a6 = yAFlipMask0 + a0;
if(a6 > 0) {
double y6 = y0 - (yNMask | 1);
double aa6 = a6 * a6, aaa6 = aa6 * a6, aaaa6 = aa6 * aa6;
int gi6 = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z));
double gx6 = GRADIENTS_3D[gi6], gy6 = GRADIENTS_3D[gi6 | 1], gz6 = GRADIENTS_3D[gi6 | 2];
double rampValue6 = gx6 * x0 + gy6 * y6 + gz6 * z0;
out[0] += aaaa6 * rampValue6;
out[1] += gx6 * aaaa6 - 8 * rampValue6 * aaa6 * x0;
out[2] += gy6 * aaaa6 - 8 * rampValue6 * aaa6 * y6;
out[3] += gz6 * aaaa6 - 8 * rampValue6 * aaa6 * z0;
} else {
double a7 = xAFlipMask0 + zAFlipMask0 + a0;
if(a7 > 0) {
double x7 = x0 - (xNMask | 1);
double z7 = z0 - (zNMask | 1);
double aa7 = a7 * a7, aaa7 = aa7 * a7, aaaa7 = aa7 * aa7;
int gi7 = gradCoordIndex(seed, i + (~xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z));
double gx7 = GRADIENTS_3D[gi7], gy7 = GRADIENTS_3D[gi7 | 1], gz7 = GRADIENTS_3D[gi7 | 2];
double rampValue7 = gx7 * x7 + gy7 * y0 + gz7 * z7;
out[0] += aaaa7 * rampValue7;
out[1] += gx7 * aaaa7 - 8 * rampValue7 * aaa7 * x7;
out[2] += gy7 * aaaa7 - 8 * rampValue7 * aaa7 * y0;
out[3] += gz7 * aaaa7 - 8 * rampValue7 * aaa7 * z7;
}
double a8 = yAFlipMask1 + a1;
if(a8 > 0) {
double y8 = (yNMask | 1) + y1;
double aa8 = a8 * a8, aaa8 = aa8 * a8, aaaa8 = aa8 * aa8;
int gi8 = gradCoordIndex(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z);
double gx8 = GRADIENTS_3D[gi8], gy8 = GRADIENTS_3D[gi8 | 1], gz8 = GRADIENTS_3D[gi8 | 2];
double rampValue8 = gx8 * x1 + gy8 * y8 + gz8 * z1;
out[0] += aaaa8 * rampValue8;
out[1] += gx8 * aaaa8 - 8 * rampValue8 * aaa8 * x1;
out[2] += gy8 * aaaa8 - 8 * rampValue8 * aaa8 * y8;
out[3] += gz8 * aaaa8 - 8 * rampValue8 * aaa8 * z1;
skip9 = true;
}
}
boolean skipD = false;
double aA = zAFlipMask0 + a0;
if(aA > 0) {
double zA = z0 - (zNMask | 1);
double aaA = aA * aA, aaaA = aaA * aA, aaaaA = aaA * aaA;
int giA = gradCoordIndex(seed, i + (xNMask & PRIME_X), j + (yNMask & PRIME_Y), k + (~zNMask & PRIME_Z));
double gxA = GRADIENTS_3D[giA], gyA = GRADIENTS_3D[giA | 1], gzA = GRADIENTS_3D[giA | 2];
double rampValueA = gxA * x0 + gyA * y0 + gzA * zA;
out[0] += aaaaA * rampValueA;
out[1] += gxA * aaaaA - 8 * rampValueA * aaaA * x0;
out[2] += gyA * aaaaA - 8 * rampValueA * aaaA * y0;
out[3] += gzA * aaaaA - 8 * rampValueA * aaaA * zA;
} else {
double aB = xAFlipMask0 + yAFlipMask0 + a0;
if(aB > 0) {
double xB = x0 - (xNMask | 1);
double yB = y0 - (yNMask | 1);
double aaB = aB * aB, aaaB = aaB * aB, aaaaB = aaB * aaB;
int giB = gradCoordIndex(seed, i + (~xNMask & PRIME_X), j + (~yNMask & PRIME_Y), k + (zNMask & PRIME_Z));
double gxB = GRADIENTS_3D[giB], gyB = GRADIENTS_3D[giB | 1], gzB = GRADIENTS_3D[giB | 2];
double rampValueB = gxB * xB + gyB * yB + gzB * z0;
out[0] += aaaaB * rampValueB;
out[1] += gxB * aaaaB - 8 * rampValueB * aaaB * xB;
out[2] += gyB * aaaaB - 8 * rampValueB * aaaB * yB;
out[3] += gzB * aaaaB - 8 * rampValueB * aaaB * z0;
}
double aC = zAFlipMask1 + a1;
if(aC > 0) {
double zC = (zNMask | 1) + z1;
double aaC = aC * aC, aaaC = aaC * aC, aaaaC = aaC * aaC;
int giC = gradCoordIndex(seed2, i + PRIME_X, j + PRIME_Y, k + (zNMask & (PRIME_Z << 1)));
double gxC = GRADIENTS_3D[giC], gyC = GRADIENTS_3D[giC | 1], gzC = GRADIENTS_3D[giC | 2];
double rampValueC = gxC * x1 + gyC * y1 + gzC * zC;
out[0] += aaaaC * rampValueC;
out[1] += gxC * aaaaC - 8 * rampValueC * aaaC * x1;
out[2] += gyC * aaaaC - 8 * rampValueC * aaaC * y1;
out[3] += gzC * aaaaC - 8 * rampValueC * aaaC * zC;
skipD = true;
}
}
if(!skip5) {
double a5 = yAFlipMask1 + zAFlipMask1 + a1;
if(a5 > 0) {
double y5 = (yNMask | 1) + y1;
double z5 = (zNMask | 1) + z1;
double aa5 = a5 * a5, aaa5 = aa5 * a5, aaaa5 = aa5 * aa5;
int gi5 = gradCoordIndex(seed2, i + PRIME_X, j + (yNMask & (PRIME_Y << 1)), k + (zNMask & (PRIME_Z << 1)));
double gx5 = GRADIENTS_3D[gi5], gy5 = GRADIENTS_3D[gi5 | 1], gz5 = GRADIENTS_3D[gi5 | 2];
double rampValue5 = gx5 * x1 + gy5 * y5 + gz5 * z5;
out[0] += aaaa5 * rampValue5;
out[1] += gx5 * aaaa5 - 8 * rampValue5 * aaa5 * x1;
out[2] += gy5 * aaaa5 - 8 * rampValue5 * aaa5 * y5;
out[3] += gz5 * aaaa5 - 8 * rampValue5 * aaa5 * z5;
}
}
if(!skip9) {
double a9 = xAFlipMask1 + zAFlipMask1 + a1;
if(a9 > 0) {
double x9 = (xNMask | 1) + x1;
double z9 = (zNMask | 1) + z1;
double aa9 = a9 * a9, aaa9 = aa9 * a9, aaaa9 = aa9 * aa9;
int gi9 = gradCoordIndex(seed2, i + (xNMask & (PRIME_X << 1)), j + PRIME_Y, k + (zNMask & (PRIME_Z << 1)));
double gx9 = GRADIENTS_3D[gi9], gy9 = GRADIENTS_3D[gi9 | 1], gz9 = GRADIENTS_3D[gi9 | 2];
double rampValue9 = gx9 * x9 + gy9 * y1 + gz9 * z9;
out[0] += aaaa9 * rampValue9;
out[1] += gx9 * aaaa9 - 8 * rampValue9 * aaa9 * x9;
out[2] += gy9 * aaaa9 - 8 * rampValue9 * aaa9 * y1;
out[3] += gz9 * aaaa9 - 8 * rampValue9 * aaa9 * z9;
}
}
if(!skipD) {
double aD = xAFlipMask1 + yAFlipMask1 + a1;
if(aD > 0) {
double xD = (xNMask | 1) + x1;
double yD = (yNMask | 1) + y1;
double aaD = aD * aD, aaaD = aaD * aD, aaaaD = aaD * aaD;
int giD = gradCoordIndex(seed2, i + (xNMask & (PRIME_X << 1)), j + (yNMask & (PRIME_Y << 1)), k + PRIME_Z);
double gxD = GRADIENTS_3D[giD], gyD = GRADIENTS_3D[giD | 1], gzD = GRADIENTS_3D[giD | 2];
double rampValueD = gxD * xD + gyD * yD + gzD * z1;
out[0] += aaaaD * rampValueD;
out[1] += gxD * aaaaD - 8 * rampValueD * aaaD * xD;
out[2] += gyD * aaaaD - 8 * rampValueD * aaaD * yD;
out[3] += gzD * aaaaD - 8 * rampValueD * aaaD * z1;
}
}
out[0] *= 9.046026385208288;
out[1] *= 9.046026385208288;
out[2] *= 9.046026385208288;
out[3] *= 9.046026385208288;
return out;
}
}
@@ -1,360 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.simplex;
/**
* NoiseSampler implementation to provide OpenSimplex2 noise.
*/
public class OpenSimplex2Sampler extends SimplexStyleSampler {
private static final double SQRT3 = 1.7320508075688772935274463415059;
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
// 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
final double G2 = (3 - SQRT3) / 6;
final double F2 = 0.5f * (SQRT3 - 1);
double s = (x + y) * F2;
x += s;
y += s;
int i = (int) Math.floor(x);
int j = (int) Math.floor(y);
double xi = x - i;
double yi = y - j;
double t = (xi + yi) * G2;
double x0 = xi - t;
double y0 = yi - t;
i *= PRIME_X;
j *= PRIME_Y;
double value = 0;
double a = 0.5 - x0 * x0 - y0 * y0;
if(a > 0) {
value = (a * a) * (a * a) * gradCoord(seed, i, j, x0, y0);
}
double c = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
if(c > 0) {
double x2 = x0 + (2 * G2 - 1);
double y2 = y0 + (2 * G2 - 1);
value += (c * c) * (c * c) * gradCoord(seed, i + PRIME_X, j + PRIME_Y, x2, y2);
}
if(y0 > x0) {
double x1 = x0 + G2;
double y1 = y0 + (G2 - 1);
double b = 0.5 - x1 * x1 - y1 * y1;
if(b > 0) {
value += (b * b) * (b * b) * gradCoord(seed, i, j + PRIME_Y, x1, y1);
}
} else {
double x1 = x0 + (G2 - 1);
double y1 = y0 + G2;
double b = 0.5 - x1 * x1 - y1 * y1;
if(b > 0) {
value += (b * b) * (b * b) * gradCoord(seed, i + PRIME_X, j, x1, y1);
}
}
return value * 99.83685446303647f;
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
// 3D OpenSimplex2Sampler case uses two offset rotated cube grids.
final double R3 = (2.0 / 3.0);
double r = (x + y + z) * R3; // Rotation, not skew
x = r - x;
y = r - y;
z = r - z;
int i = (int) Math.round(x);
int j = (int) Math.round(y);
int k = (int) Math.round(z);
double x0 = x - i;
double y0 = y - j;
double z0 = z - k;
int xNSign = (int) (-1.0 - x0) | 1;
int yNSign = (int) (-1.0 - y0) | 1;
int zNSign = (int) (-1.0 - z0) | 1;
double ax0 = xNSign * -x0;
double ay0 = yNSign * -y0;
double az0 = zNSign * -z0;
i *= PRIME_X;
j *= PRIME_Y;
k *= PRIME_Z;
double value = 0;
double a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
for(int l = 0; ; l++) {
if(a > 0) {
value += (a * a) * (a * a) * gradCoord(seed, i, j, k, x0, y0, z0);
}
if(ax0 >= ay0 && ax0 >= az0) {
double b = a + ax0 + ax0;
if(b > 1) {
b -= 1;
value += (b * b) * (b * b) * gradCoord(seed, i - xNSign * PRIME_X, j, k, x0 + xNSign, y0, z0);
}
} else if(ay0 > ax0 && ay0 >= az0) {
double b = a + ay0 + ay0;
if(b > 1) {
b -= 1;
value += (b * b) * (b * b) * gradCoord(seed, i, j - yNSign * PRIME_Y, k, x0, y0 + yNSign, z0);
}
} else {
double b = a + az0 + az0;
if(b > 1) {
b -= 1;
value += (b * b) * (b * b) * gradCoord(seed, i, j, k - zNSign * PRIME_Z, x0, y0, z0 + zNSign);
}
}
if(l == 1) break;
ax0 = 0.5 - ax0;
ay0 = 0.5 - ay0;
az0 = 0.5 - az0;
x0 = xNSign * ax0;
y0 = yNSign * ay0;
z0 = zNSign * az0;
a += (0.75 - ax0) - (ay0 + az0);
i += (xNSign >> 1) & PRIME_X;
j += (yNSign >> 1) & PRIME_Y;
k += (zNSign >> 1) & PRIME_Z;
xNSign = -xNSign;
yNSign = -yNSign;
zNSign = -zNSign;
seed = ~seed;
}
return value * 32.69428253173828125;
}
@Override
public boolean isDifferentiable() {
return true;
}
@Override
public double[] getNoiseDerivativeRaw(long sl, double x, double y) {
int seed = (int) sl;
// 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
final double G2 = (3 - SQRT3) / 6;
final double F2 = 0.5f * (SQRT3 - 1);
double s = (x + y) * F2;
x += s;
y += s;
int i = (int) Math.floor(x);
int j = (int) Math.floor(y);
double xi = x - i;
double yi = y - j;
double t = (xi + yi) * G2;
double x0 = xi - t;
double y0 = yi - t;
i *= PRIME_X;
j *= PRIME_Y;
double[] out = { 0.0f, 0.0f, 0.0f };
double a = 0.5 - x0 * x0 - y0 * y0;
if(a > 0) {
double aa = a * a, aaa = aa * a, aaaa = aa * aa;
int gi = gradCoordIndex(seed, i, j);
double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1];
double rampValue = gx * x0 + gy * y0;
out[0] += aaaa * rampValue;
out[1] += gx * aaaa - 8 * rampValue * aaa * x0;
out[2] += gy * aaaa - 8 * rampValue * aaa * y0;
}
double c = 2 * (1 - 2 * G2) * (1 / G2 - 2) * t + ((-2 * (1 - 2 * G2) * (1 - 2 * G2)) + a);
if(c > 0) {
double x2 = x0 + (2 * G2 - 1);
double y2 = y0 + (2 * G2 - 1);
double cc = c * c, ccc = cc * c, cccc = cc * cc;
int gi = gradCoordIndex(seed, i + PRIME_X, j + PRIME_Y);
double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1];
double rampValue = gx * x2 + gy * y2;
out[0] += cccc * rampValue;
out[1] += gx * cccc - 8 * rampValue * ccc * x2;
out[2] += gy * cccc - 8 * rampValue * ccc * y2;
}
if(y0 > x0) {
double x1 = x0 + G2;
double y1 = y0 + (G2 - 1);
double b = 0.5 - x1 * x1 - y1 * y1;
if(b > 0) {
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
int gi = gradCoordIndex(seed, i, j + PRIME_Y);
double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1];
double rampValue = gx * x1 + gy * y1;
out[0] += bbbb * rampValue;
out[1] += gx * bbbb - 8 * rampValue * bbb * x1;
out[2] += gy * bbbb - 8 * rampValue * bbb * y1;
}
} else {
double x1 = x0 + (G2 - 1);
double y1 = y0 + G2;
double b = 0.5 - x1 * x1 - y1 * y1;
if(b > 0) {
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
int gi = gradCoordIndex(seed, i + PRIME_X, j);
double gx = GRADIENTS_2_D[gi], gy = GRADIENTS_2_D[gi | 1];
double rampValue = gx * x1 + gy * y1;
out[0] += bbbb * rampValue;
out[1] += gx * bbbb - 8 * rampValue * bbb * x1;
out[2] += gy * bbbb - 8 * rampValue * bbb * y1;
}
}
out[0] *= 99.83685446303647f;
out[1] *= 99.83685446303647f;
out[2] *= 99.83685446303647f;
return out;
}
@Override
public double[] getNoiseDerivativeRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
// 3D OpenSimplex2Sampler case uses two offset rotated cube grids.
final double R3 = (2.0 / 3.0);
double r = (x + y + z) * R3; // Rotation, not skew
x = r - x;
y = r - y;
z = r - z;
int i = (int) Math.round(x);
int j = (int) Math.round(y);
int k = (int) Math.round(z);
double x0 = x - i;
double y0 = y - j;
double z0 = z - k;
int xNSign = (int) (-1.0 - x0) | 1;
int yNSign = (int) (-1.0 - y0) | 1;
int zNSign = (int) (-1.0 - z0) | 1;
double ax0 = xNSign * -x0;
double ay0 = yNSign * -y0;
double az0 = zNSign * -z0;
i *= PRIME_X;
j *= PRIME_Y;
k *= PRIME_Z;
double[] out = { 0.0f, 0.0f, 0.0f, 0.0f };
double a = (0.6f - x0 * x0) - (y0 * y0 + z0 * z0);
for(int l = 0; ; l++) {
if(a > 0) {
double aa = a * a, aaa = aa * a, aaaa = aa * aa;
int gi = gradCoordIndex(seed, i, j, k);
double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2];
double rampValue = gx * x0 + gy * y0 + gz * z0;
out[0] += aaaa * rampValue;
out[1] += gx * aaaa - 8 * rampValue * aaa * x0;
out[1] += gy * aaaa - 8 * rampValue * aaa * y0;
out[2] += gz * aaaa - 8 * rampValue * aaa * z0;
}
if(ax0 >= ay0 && ax0 >= az0) {
double b = a + ax0 + ax0;
if(b > 1) {
b -= 1;
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
int gi = gradCoordIndex(seed, i - xNSign * PRIME_X, j, k);
double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2];
double rampValue = gx * (x0 + xNSign) + gy * y0 + gz * z0;
out[0] += bbbb * rampValue;
out[1] += gx * bbbb - 8 * rampValue * bbb * (x0 + xNSign);
out[1] += gy * bbbb - 8 * rampValue * bbb * y0;
out[2] += gz * bbbb - 8 * rampValue * bbb * z0;
}
} else if(ay0 > ax0 && ay0 >= az0) {
double b = a + ay0 + ay0;
if(b > 1) {
b -= 1;
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
int gi = gradCoordIndex(seed, i, j - yNSign * PRIME_Y, k);
double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2];
double rampValue = gx * x0 + gy * (y0 + yNSign) + gz * z0;
out[0] += bbbb * rampValue;
out[1] += gx * bbbb - 8 * rampValue * bbb * x0;
out[1] += gy * bbbb - 8 * rampValue * bbb * (y0 + yNSign);
out[2] += gz * bbbb - 8 * rampValue * bbb * z0;
}
} else {
double b = a + az0 + az0;
if(b > 1) {
b -= 1;
double bb = b * b, bbb = bb * b, bbbb = bb * bb;
int gi = gradCoordIndex(seed, i, j, k - zNSign * PRIME_Z);
double gx = GRADIENTS_3D[gi], gy = GRADIENTS_3D[gi | 1], gz = GRADIENTS_3D[gi | 2];
double rampValue = gx * x0 + gy * y0 + gz * (z0 + zNSign);
out[0] += bbbb * rampValue;
out[1] += gx * bbbb - 8 * rampValue * bbb * x0;
out[1] += gy * bbbb - 8 * rampValue * bbb * y0;
out[2] += gz * bbbb - 8 * rampValue * bbb * (z0 + zNSign);
}
}
if(l == 1) break;
ax0 = 0.5 - ax0;
ay0 = 0.5 - ay0;
az0 = 0.5 - az0;
x0 = xNSign * ax0;
y0 = yNSign * ay0;
z0 = zNSign * az0;
a += (0.75 - ax0) - (ay0 + az0);
i += (xNSign >> 1) & PRIME_X;
j += (yNSign >> 1) & PRIME_Y;
k += (zNSign >> 1) & PRIME_Z;
xNSign = -xNSign;
yNSign = -yNSign;
zNSign = -zNSign;
seed = ~seed;
}
out[0] *= 32.69428253173828125;
out[1] *= 32.69428253173828125;
out[2] *= 32.69428253173828125;
out[3] *= 32.69428253173828125;
return out;
}
}
@@ -1,77 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.simplex;
import com.dfsek.terra.api.util.MathUtil;
/**
* NoiseSampler implementation to provide Perlin Noise.
*/
public class PerlinSampler extends SimplexStyleSampler {
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x0 = (int) Math.floor(x);
int y0 = (int) Math.floor(y);
double xd0 = x - x0;
double yd0 = y - y0;
double xd1 = xd0 - 1;
double yd1 = yd0 - 1;
double xs = MathUtil.interpQuintic(xd0);
double ys = MathUtil.interpQuintic(yd0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
int x1 = x0 + PRIME_X;
int y1 = y0 + PRIME_Y;
double xf0 = MathUtil.lerp(xs, gradCoord(seed, x0, y0, xd0, yd0), gradCoord(seed, x1, y0, xd1, yd0));
double xf1 = MathUtil.lerp(xs, gradCoord(seed, x0, y1, xd0, yd1), gradCoord(seed, x1, y1, xd1, yd1));
return MathUtil.lerp(ys, xf0, xf1) * 1.4247691104677813;
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x0 = (int) Math.floor(x);
int y0 = (int) Math.floor(y);
int z0 = (int) Math.floor(z);
double xd0 = x - x0;
double yd0 = y - y0;
double zd0 = z - z0;
double xd1 = xd0 - 1;
double yd1 = yd0 - 1;
double zd1 = zd0 - 1;
double xs = MathUtil.interpQuintic(xd0);
double ys = MathUtil.interpQuintic(yd0);
double zs = MathUtil.interpQuintic(zd0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
z0 *= PRIME_Z;
int x1 = x0 + PRIME_X;
int y1 = y0 + PRIME_Y;
int z1 = z0 + PRIME_Z;
double xf00 = MathUtil.lerp(xs, gradCoord(seed, x0, y0, z0, xd0, yd0, zd0), gradCoord(seed, x1, y0, z0, xd1, yd0, zd0));
double xf10 = MathUtil.lerp(xs, gradCoord(seed, x0, y1, z0, xd0, yd1, zd0), gradCoord(seed, x1, y1, z0, xd1, yd1, zd0));
double xf01 = MathUtil.lerp(xs, gradCoord(seed, x0, y0, z1, xd0, yd0, zd1), gradCoord(seed, x1, y0, z1, xd1, yd0, zd1));
double xf11 = MathUtil.lerp(xs, gradCoord(seed, x0, y1, z1, xd0, yd1, zd1), gradCoord(seed, x1, y1, z1, xd1, yd1, zd1));
double yf0 = MathUtil.lerp(ys, xf00, xf10);
double yf1 = MathUtil.lerp(ys, xf01, xf11);
return MathUtil.lerp(zs, yf0, yf1) * 0.964921414852142333984375;
}
}
@@ -1,249 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.simplex;
public class SimplexSampler extends SimplexStyleSampler {
private static final Double2[] GRAD_2D = {
new Double2(-1, -1), new Double2(1, -1), new Double2(-1, 1), new Double2(1, 1),
new Double2(0, -1), new Double2(-1, 0), new Double2(0, 1), new Double2(1, 0),
};
private static final Double3[] GRAD_3D = {
new Double3(1, 1, 0), new Double3(-1, 1, 0), new Double3(1, -1, 0), new Double3(-1, -1, 0),
new Double3(1, 0, 1), new Double3(-1, 0, 1), new Double3(1, 0, -1), new Double3(-1, 0, -1),
new Double3(0, 1, 1), new Double3(0, -1, 1), new Double3(0, 1, -1), new Double3(0, -1, -1),
new Double3(1, 1, 0), new Double3(0, -1, 1), new Double3(-1, 1, 0), new Double3(0, -1, -1),
};
private static final double F2 = 1.0 / 2.0;
private static final double F3 = (1.0 / 3.0);
private static final double G2 = 1.0 / 4.0;
private static final double G3 = (1.0 / 6.0);
private static final double G33 = G3 * 3 - 1;
private static final int X_PRIME = 1619;
private static final int Y_PRIME = 31337;
private static final int Z_PRIME = 6971;
private static double gradCoord3D(int seed, int x, int y, int z, double xd, double yd, double zd) {
int hash = seed;
hash ^= X_PRIME * x;
hash ^= Y_PRIME * y;
hash ^= Z_PRIME * z;
hash = hash * hash * hash * 60493;
hash = (hash >> 13) ^ hash;
Double3 g = GRAD_3D[hash & 15];
return xd * g.x + yd * g.y + zd * g.z;
}
private static double gradCoord2D(int seed, int x, int y, double xd, double yd) {
int hash = seed;
hash ^= X_PRIME * x;
hash ^= Y_PRIME * y;
hash = hash * hash * hash * 60493;
hash = (hash >> 13) ^ hash;
Double2 g = GRAD_2D[hash & 7];
return xd * g.x + yd * g.y;
}
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
double t = (x + y) * F2;
int i = (int) Math.floor(x + t);
int j = (int) Math.floor(y + t);
t = (i + j) * G2;
double X0 = i - t;
double Y0 = j - t;
double x0 = x - X0;
double y0 = y - Y0;
int i1, j1;
if(x0 > y0) {
i1 = 1;
j1 = 0;
} else {
i1 = 0;
j1 = 1;
}
double x1 = x0 - i1 + G2;
double y1 = y0 - j1 + G2;
double x2 = x0 - 1 + F2;
double y2 = y0 - 1 + F2;
double n0, n1, n2;
t = 0.5 - x0 * x0 - y0 * y0;
if(t < 0) {
n0 = 0;
} else {
t *= t;
n0 = t * t * gradCoord2D(seed, i, j, x0, y0);
}
t = 0.5 - x1 * x1 - y1 * y1;
if(t < 0) {
n1 = 0;
} else {
t *= t;
n1 = t * t * gradCoord2D(seed, i + i1, j + j1, x1, y1);
}
t = 0.5 - x2 * x2 - y2 * y2;
if(t < 0) {
n2 = 0;
} else {
t *= t;
n2 = t * t * gradCoord2D(seed, i + 1, j + 1, x2, y2);
}
return 50 * (n0 + n1 + n2);
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
double t = (x + y + z) * F3;
int i = (int) Math.floor(x + t);
int j = (int) Math.floor(y + t);
int k = (int) Math.floor(z + t);
t = (i + j + k) * G3;
double x0 = x - (i - t);
double y0 = y - (j - t);
double z0 = z - (k - t);
int i1, j1, k1;
int i2, j2, k2;
if(x0 >= y0) {
if(y0 >= z0) {
i1 = 1;
j1 = 0;
k1 = 0;
i2 = 1;
j2 = 1;
k2 = 0;
} else if(x0 >= z0) {
i1 = 1;
j1 = 0;
k1 = 0;
i2 = 1;
j2 = 0;
k2 = 1;
} else // x0 < z0
{
i1 = 0;
j1 = 0;
k1 = 1;
i2 = 1;
j2 = 0;
k2 = 1;
}
} else // x0 < y0
{
if(y0 < z0) {
i1 = 0;
j1 = 0;
k1 = 1;
i2 = 0;
j2 = 1;
k2 = 1;
} else if(x0 < z0) {
i1 = 0;
j1 = 1;
k1 = 0;
i2 = 0;
j2 = 1;
k2 = 1;
} else // x0 >= z0
{
i1 = 0;
j1 = 1;
k1 = 0;
i2 = 1;
j2 = 1;
k2 = 0;
}
}
double x1 = x0 - i1 + G3;
double y1 = y0 - j1 + G3;
double z1 = z0 - k1 + G3;
double x2 = x0 - i2 + F3;
double y2 = y0 - j2 + F3;
double z2 = z0 - k2 + F3;
double x3 = x0 + G33;
double y3 = y0 + G33;
double z3 = z0 + G33;
double n0, n1, n2, n3;
t = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
if(t < 0) n0 = 0;
else {
t *= t;
n0 = t * t * gradCoord3D(seed, i, j, k, x0, y0, z0);
}
t = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
if(t < 0) {
n1 = 0;
} else {
t *= t;
n1 = t * t * gradCoord3D(seed, i + i1, j + j1, k + k1, x1, y1, z1);
}
t = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
if(t < 0) {
n2 = 0;
} else {
t *= t;
n2 = t * t * gradCoord3D(seed, i + i2, j + j2, k + k2, x2, y2, z2);
}
t = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
if(t < 0) {
n3 = 0;
} else {
t *= t;
n3 = t * t * gradCoord3D(seed, i + 1, j + 1, k + 1, x3, y3, z3);
}
return 32 * (n0 + n1 + n2 + n3);
}
private static class Double2 {
public final double x, y;
public Double2(double x, double y) {
this.x = x;
this.y = y;
}
}
private static class Double3 {
public final double x, y, z;
public Double3(double x, double y, double z) {
this.x = x;
this.y = y;
this.z = z;
}
}
}
@@ -1,131 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.simplex;
import com.dfsek.terra.addons.noise.samplers.noise.DerivativeNoiseFunction;
/**
* Abstract NoiseSampler implementation for simplex-style noise functions.
*/
public abstract class SimplexStyleSampler extends DerivativeNoiseFunction {
protected static final double[] GRADIENTS_2_D = {
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
0.130526192220052d, 0.99144486137381d, 0.38268343236509d, 0.923879532511287d, 0.608761429008721d, 0.793353340291235d,
0.793353340291235d, 0.608761429008721d, 0.923879532511287d, 0.38268343236509d, 0.99144486137381d, 0.130526192220051d,
0.99144486137381d, -0.130526192220051d, 0.923879532511287d, -0.38268343236509d, 0.793353340291235d, -0.60876142900872d,
0.608761429008721d, -0.793353340291235d, 0.38268343236509d, -0.923879532511287d, 0.130526192220052d, -0.99144486137381d,
-0.130526192220052d, -0.99144486137381d, -0.38268343236509d, -0.923879532511287d, -0.608761429008721d, -0.793353340291235d,
-0.793353340291235d, -0.608761429008721d, -0.923879532511287d, -0.38268343236509d, -0.99144486137381d, -0.130526192220052d,
-0.99144486137381d, 0.130526192220051d, -0.923879532511287d, 0.38268343236509d, -0.793353340291235d, 0.608761429008721d,
-0.608761429008721d, 0.793353340291235d, -0.38268343236509d, 0.923879532511287d, -0.130526192220052d, 0.99144486137381d,
0.38268343236509d, 0.923879532511287d, 0.923879532511287d, 0.38268343236509d, 0.923879532511287d, -0.38268343236509d,
0.38268343236509d, -0.923879532511287d, -0.38268343236509d, -0.923879532511287d, -0.923879532511287d, -0.38268343236509d,
-0.923879532511287d, 0.38268343236509d, -0.38268343236509d, 0.923879532511287d,
};
protected static final double[] GRADIENTS_3D = {
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
0, 1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0,
1, 0, 1, 0, -1, 0, 1, 0, 1, 0, -1, 0, -1, 0, -1, 0,
1, 1, 0, 0, -1, 1, 0, 0, 1, -1, 0, 0, -1, -1, 0, 0,
1, 1, 0, 0, 0, -1, 1, 0, -1, 1, 0, 0, 0, -1, -1, 0
};
protected static int gradCoordIndex(int seed, int xPrimed, int yPrimed) {
int hash = hash(seed, xPrimed, yPrimed);
hash ^= hash >> 15;
hash &= 127 << 1;
return hash;
}
protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) {
int index = gradCoordIndex(seed, xPrimed, yPrimed);
double xg = GRADIENTS_2_D[index];
double yg = GRADIENTS_2_D[index | 1];
return xd * xg + yd * yg;
}
protected static int gradCoordIndex(int seed, int xPrimed, int yPrimed, int zPrimed) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
hash ^= hash >> 15;
hash &= 63 << 2;
return hash;
}
protected static double gradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, double xd, double yd, double zd) {
int index = gradCoordIndex(seed, xPrimed, yPrimed, zPrimed);
double xg = GRADIENTS_3D[index];
double yg = GRADIENTS_3D[index | 1];
double zg = GRADIENTS_3D[index | 2];
return xd * xg + yd * yg + zd * zg;
}
@Override
public double[] getNoiseDerivativeRaw(long seed, double x, double y) {
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
}
@Override
public double[] getNoiseDerivativeRaw(long seed, double x, double y, double z) {
throw new UnsupportedOperationException("Implementation failed to check or set isDifferentiable correctly");
}
@Override
public boolean isDifferentiable() {
return false;
}
}
@@ -1,112 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.value;
import com.dfsek.terra.api.util.MathUtil;
public class ValueCubicSampler extends ValueStyleNoise {
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x1 = (int) Math.floor(x);
int y1 = (int) Math.floor(y);
double xs = x - x1;
double ys = y - y1;
x1 *= PRIME_X;
y1 *= PRIME_Y;
int x0 = x1 - PRIME_X;
int y0 = y1 - PRIME_Y;
int x2 = x1 + PRIME_X;
int y2 = y1 + PRIME_Y;
int x3 = x1 + (PRIME_X << 1);
int y3 = y1 + (PRIME_Y << 1);
return MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), valCoord(seed, x2, y0), valCoord(seed, x3, y0),
xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), valCoord(seed, x2, y1), valCoord(seed, x3, y1),
xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2), valCoord(seed, x1, y2), valCoord(seed, x2, y2), valCoord(seed, x3, y2),
xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3), valCoord(seed, x1, y3), valCoord(seed, x2, y3), valCoord(seed, x3, y3),
xs),
ys) * (1 / (1.5 * 1.5));
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x1 = (int) Math.floor(x);
int y1 = (int) Math.floor(y);
int z1 = (int) Math.floor(z);
double xs = x - x1;
double ys = y - y1;
double zs = z - z1;
x1 *= PRIME_X;
y1 *= PRIME_Y;
z1 *= PRIME_Z;
int x0 = x1 - PRIME_X;
int y0 = y1 - PRIME_Y;
int z0 = z1 - PRIME_Z;
int x2 = x1 + PRIME_X;
int y2 = y1 + PRIME_Y;
int z2 = z1 + PRIME_Z;
int x3 = x1 + (PRIME_X << 1);
int y3 = y1 + (PRIME_Y << 1);
int z3 = z1 + (PRIME_Z << 1);
return MathUtil.cubicLerp(
MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), valCoord(seed, x2, y0, z0),
valCoord(seed, x3, y0, z0), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), valCoord(seed, x2, y1, z0),
valCoord(seed, x3, y1, z0), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z0), valCoord(seed, x1, y2, z0), valCoord(seed, x2, y2, z0),
valCoord(seed, x3, y2, z0), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z0), valCoord(seed, x1, y3, z0), valCoord(seed, x2, y3, z0),
valCoord(seed, x3, y3, z0), xs),
ys),
MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), valCoord(seed, x2, y0, z1),
valCoord(seed, x3, y0, z1), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), valCoord(seed, x2, y1, z1),
valCoord(seed, x3, y1, z1), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z1), valCoord(seed, x1, y2, z1), valCoord(seed, x2, y2, z1),
valCoord(seed, x3, y2, z1), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z1), valCoord(seed, x1, y3, z1), valCoord(seed, x2, y3, z1),
valCoord(seed, x3, y3, z1), xs),
ys),
MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0, z2), valCoord(seed, x1, y0, z2), valCoord(seed, x2, y0, z2),
valCoord(seed, x3, y0, z2), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z2), valCoord(seed, x1, y1, z2), valCoord(seed, x2, y1, z2),
valCoord(seed, x3, y1, z2), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z2), valCoord(seed, x1, y2, z2), valCoord(seed, x2, y2, z2),
valCoord(seed, x3, y2, z2), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z2), valCoord(seed, x1, y3, z2), valCoord(seed, x2, y3, z2),
valCoord(seed, x3, y3, z2), xs),
ys),
MathUtil.cubicLerp(
MathUtil.cubicLerp(valCoord(seed, x0, y0, z3), valCoord(seed, x1, y0, z3), valCoord(seed, x2, y0, z3),
valCoord(seed, x3, y0, z3), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y1, z3), valCoord(seed, x1, y1, z3), valCoord(seed, x2, y1, z3),
valCoord(seed, x3, y1, z3), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y2, z3), valCoord(seed, x1, y2, z3), valCoord(seed, x2, y2, z3),
valCoord(seed, x3, y2, z3), xs),
MathUtil.cubicLerp(valCoord(seed, x0, y3, z3), valCoord(seed, x1, y3, z3), valCoord(seed, x2, y3, z3),
valCoord(seed, x3, y3, z3), xs),
ys),
zs) * (1 / (1.5 * 1.5 * 1.5));
}
}
@@ -1,62 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.value;
import com.dfsek.terra.api.util.MathUtil;
public class ValueSampler extends ValueStyleNoise {
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x0 = (int) Math.floor(x);
int y0 = (int) Math.floor(y);
double xs = MathUtil.interpHermite(x - x0);
double ys = MathUtil.interpHermite(y - y0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
int x1 = x0 + PRIME_X;
int y1 = y0 + PRIME_Y;
double xf0 = MathUtil.lerp(xs, valCoord(seed, x0, y0), valCoord(seed, x1, y0));
double xf1 = MathUtil.lerp(xs, valCoord(seed, x0, y1), valCoord(seed, x1, y1));
return MathUtil.lerp(ys, xf0, xf1);
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x0 = (int) Math.floor(x);
int y0 = (int) Math.floor(y);
int z0 = (int) Math.floor(z);
double xs = MathUtil.interpHermite(x - x0);
double ys = MathUtil.interpHermite(y - y0);
double zs = MathUtil.interpHermite(z - z0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
z0 *= PRIME_Z;
int x1 = x0 + PRIME_X;
int y1 = y0 + PRIME_Y;
int z1 = z0 + PRIME_Z;
double xf00 = MathUtil.lerp(xs, valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0));
double xf10 = MathUtil.lerp(xs, valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0));
double xf01 = MathUtil.lerp(xs, valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1));
double xf11 = MathUtil.lerp(xs, valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1));
double yf0 = MathUtil.lerp(ys, xf00, xf10);
double yf1 = MathUtil.lerp(ys, xf01, xf11);
return MathUtil.lerp(zs, yf0, yf1);
}
}
@@ -1,30 +0,0 @@
/*
* Copyright (c) 2020-2025 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.samplers.noise.value;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
public abstract class ValueStyleNoise extends NoiseFunction {
protected static double valCoord(int seed, int xPrimed, int yPrimed) {
int hash = hash(seed, xPrimed, yPrimed);
hash *= hash;
hash ^= hash << 19;
return hash * (1 / 2147483648.0);
}
protected static double valCoord(int seed, int xPrimed, int yPrimed, int zPrimed) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
hash *= hash;
hash ^= hash << 19;
return hash * (1 / 2147483648.0);
}
}