Initial commit

This commit is contained in:
dfsek 2021-10-17 15:07:58 -07:00
commit 7e0fd93708
56 changed files with 3759 additions and 0 deletions

View File

@ -0,0 +1,3 @@
# config-noise-function
Registers the default noise functions.

View File

@ -0,0 +1,2 @@
dependencies {
}

View File

@ -0,0 +1,115 @@
package com.dfsek.terra.addons.noise;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Supplier;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
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.noise.CellularNoiseTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.ConstantNoiseTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.ExpressionFunctionTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.GaborNoiseTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.SimpleNoiseTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.BrownianMotionTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.PingPongTemplate;
import com.dfsek.terra.addons.noise.config.templates.noise.fractal.RidgedFractalTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.ClampNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizerTemplate;
import com.dfsek.terra.addons.noise.samplers.noise.CellularSampler;
import com.dfsek.terra.addons.noise.samplers.noise.random.GaussianNoiseSampler;
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.TerraAddon;
import com.dfsek.terra.api.addon.annotations.Addon;
import com.dfsek.terra.api.addon.annotations.Author;
import com.dfsek.terra.api.addon.annotations.Version;
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.NoiseSampler;
import com.dfsek.terra.api.registry.CheckedRegistry;
import com.dfsek.terra.api.util.reflection.TypeKey;
@Addon("config-noise-function")
@Author("Terra")
@Version("1.0.0")
public class NoiseAddon extends TerraAddon {
public static final TypeKey<Supplier<ObjectTemplate<NoiseSampler>>> NOISE_SAMPLER_TOKEN = new TypeKey<>() {
};
@Inject
private Platform plugin;
@Override
public void initialize() {
plugin.getEventManager()
.getHandler(FunctionalEventHandler.class)
.register(this, ConfigPackPreLoadEvent.class)
.then(event -> {
CheckedRegistry<Supplier<ObjectTemplate<NoiseSampler>>> noiseRegistry = event.getPack().getOrCreateRegistry(
NOISE_SAMPLER_TOKEN);
event.getPack()
.applyLoader(CellularSampler.DistanceFunction.class,
(t, o, l) -> CellularSampler.DistanceFunction.valueOf((String) o))
.applyLoader(CellularSampler.ReturnType.class, (t, o, l) -> CellularSampler.ReturnType.valueOf((String) o))
.applyLoader(DimensionApplicableNoiseSampler.class, DimensionApplicableNoiseSampler::new)
.applyLoader(FunctionTemplate.class, FunctionTemplate::new);
noiseRegistry.register("LINEAR", LinearNormalizerTemplate::new);
noiseRegistry.register("NORMAL", NormalNormalizerTemplate::new);
noiseRegistry.register("CLAMP", ClampNormalizerTemplate::new);
noiseRegistry.register("IMAGE", ImageSamplerTemplate::new);
noiseRegistry.register("DOMAIN_WARP", DomainWarpTemplate::new);
noiseRegistry.register("FBM", BrownianMotionTemplate::new);
noiseRegistry.register("PING_PONG", PingPongTemplate::new);
noiseRegistry.register("RIDGED", RidgedFractalTemplate::new);
noiseRegistry.register("OPEN_SIMPLEX_2", () -> new SimpleNoiseTemplate(OpenSimplex2Sampler::new));
noiseRegistry.register("OPEN_SIMPLEX_2S", () -> new SimpleNoiseTemplate(OpenSimplex2SSampler::new));
noiseRegistry.register("PERLIN", () -> new SimpleNoiseTemplate(PerlinSampler::new));
noiseRegistry.register("SIMPLEX", () -> new SimpleNoiseTemplate(SimplexSampler::new));
noiseRegistry.register("GABOR", GaborNoiseTemplate::new);
noiseRegistry.register("VALUE", () -> new SimpleNoiseTemplate(ValueSampler::new));
noiseRegistry.register("VALUE_CUBIC", () -> new SimpleNoiseTemplate(ValueCubicSampler::new));
noiseRegistry.register("CELLULAR", CellularNoiseTemplate::new);
noiseRegistry.register("WHITE_NOISE", () -> new SimpleNoiseTemplate(WhiteNoiseSampler::new));
noiseRegistry.register("GAUSSIAN", () -> new SimpleNoiseTemplate(GaussianNoiseSampler::new));
noiseRegistry.register("CONSTANT", ConstantNoiseTemplate::new);
noiseRegistry.register("KERNEL", KernelTemplate::new);
Map<String, DimensionApplicableNoiseSampler> packSamplers = new LinkedHashMap<>();
Map<String, FunctionTemplate> packFunctions = new LinkedHashMap<>();
noiseRegistry.register("EXPRESSION", () -> new ExpressionFunctionTemplate(packSamplers, packFunctions));
NoiseConfigPackTemplate template = new NoiseConfigPackTemplate();
event.loadTemplate(template);
packSamplers.putAll(template.getSamplers());
packFunctions.putAll(template.getFunctions());
})
.failThrough();
}
}

View File

@ -0,0 +1,30 @@
package com.dfsek.terra.addons.noise;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ConfigTemplate;
import java.util.LinkedHashMap;
import java.util.Map;
import com.dfsek.terra.addons.noise.config.DimensionApplicableNoiseSampler;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.api.config.meta.Meta;
public class NoiseConfigPackTemplate implements ConfigTemplate {
@Value("noise")
private @Meta Map<String, @Meta DimensionApplicableNoiseSampler> noiseBuilderMap;
@Value("functions")
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> expressions = new LinkedHashMap<>();
public Map<String, DimensionApplicableNoiseSampler> getSamplers() {
return noiseBuilderMap;
}
public LinkedHashMap<String, FunctionTemplate> getFunctions() {
return expressions;
}
}

View File

@ -0,0 +1,29 @@
package com.dfsek.terra.addons.noise.config;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
public class DimensionApplicableNoiseSampler implements ObjectTemplate<DimensionApplicableNoiseSampler> {
@Value("dimensions")
private @Meta int dimensions;
@Value(".")
private @Meta NoiseSampler sampler;
@Override
public DimensionApplicableNoiseSampler get() {
return this;
}
public int getDimensions() {
return dimensions;
}
public NoiseSampler getSampler() {
return sampler;
}
}

View File

@ -0,0 +1,27 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.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;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class DomainWarpTemplate extends SamplerTemplate<DomainWarpedSampler> {
@Value("warp")
private @Meta NoiseSampler warp;
@Value("function")
private @Meta NoiseSampler function;
@Value("amplitude")
@Default
private @Meta double amplitude = 1;
@Override
public NoiseSampler get() {
return new DomainWarpedSampler(function, warp, amplitude);
}
}

View File

@ -0,0 +1,31 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import java.util.List;
import com.dfsek.terra.api.config.meta.Meta;
@SuppressWarnings("unused")
public class FunctionTemplate implements ObjectTemplate<FunctionTemplate> {
@Value("arguments")
private List<String> args;
@Value("expression")
private @Meta String function;
@Override
public FunctionTemplate get() {
return this;
}
public List<String> getArgs() {
return args;
}
public String getFunction() {
return function;
}
}

View File

@ -0,0 +1,28 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.tectonic.annotations.Value;
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> {
@Value("image")
private @Meta BufferedImage image;
@Value("frequency")
private @Meta double frequency;
@Value("channel")
private ImageSampler.@Meta Channel channel;
@Override
public NoiseSampler get() {
return new ImageSampler(image, channel, frequency);
}
}

View File

@ -0,0 +1,62 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.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;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class KernelTemplate extends SamplerTemplate<KernelSampler> {
@Value("kernel")
private @Meta List<@Meta List<@Meta Double>> kernel;
@Value("factor")
@Default
private @Meta double factor = 1;
@Value("function")
private @Meta NoiseSampler function;
@Value("frequency")
@Default
private @Meta double frequency = 1;
@Override
public NoiseSampler get() {
double[][] k = new double[kernel.size()][kernel.get(0).size()];
for(int x = 0; x < kernel.size(); x++) {
for(int y = 0; y < kernel.get(x).size(); y++) {
k[x][y] = kernel.get(x).get(y) * factor;
}
}
KernelSampler sampler = new KernelSampler(k, function);
sampler.setFrequency(frequency);
return sampler;
}
@Override
public boolean validate() throws ValidationException {
if(kernel.isEmpty()) throw new ValidationException("Kernel must not be empty.");
int len = kernel.get(0).size();
if(len == 0) throw new ValidationException("Kernel row must contain data.");
for(int i = 0; i < kernel.size(); i++) {
if(kernel.get(i).size() != len)
throw new ValidationException("Kernel row " + i + " size mismatch. Expected " + len + ", found " + kernel.get(i).size());
}
return super.validate();
}
}

View File

@ -0,0 +1,28 @@
package com.dfsek.terra.addons.noise.config.templates;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.config.ValidatedConfigTemplate;
import com.dfsek.tectonic.exception.ValidationException;
import com.dfsek.tectonic.loading.object.ObjectTemplate;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings("FieldMayBeFinal")
public abstract class SamplerTemplate<T extends NoiseSampler> implements ValidatedConfigTemplate, ObjectTemplate<NoiseSampler> {
@Value("dimensions")
@Default
private @Meta int dimensions = 2;
@Override
public boolean validate() throws ValidationException {
if(dimensions != 2 && dimensions != 3) throw new ValidationException("Illegal amount of dimensions: " + dimensions);
return true;
}
public int getDimensions() {
return dimensions;
}
}

View File

@ -0,0 +1,42 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.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;
@SuppressWarnings("FieldMayBeFinal")
public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
@Value("distance")
@Default
private CellularSampler.@Meta DistanceFunction cellularDistanceFunction = CellularSampler.DistanceFunction.EuclideanSq;
@Value("return")
@Default
private CellularSampler.@Meta ReturnType cellularReturnType = CellularSampler.ReturnType.Distance;
@Value("jitter")
@Default
private @Meta double cellularJitter = 1.0D;
@Value("lookup")
@Default
private @Meta NoiseSampler lookup = new OpenSimplex2Sampler();
@Override
public NoiseSampler get() {
CellularSampler sampler = new CellularSampler();
sampler.setNoiseLookup(lookup);
sampler.setFrequency(frequency);
sampler.setJitterModifier(cellularJitter);
sampler.setReturnType(cellularReturnType);
sampler.setDistanceFunction(cellularDistanceFunction);
sampler.setSalt(salt);
return sampler;
}
}

View File

@ -0,0 +1,22 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.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;
@SuppressWarnings("FieldMayBeFinal")
public class ConstantNoiseTemplate extends SamplerTemplate<ConstantSampler> {
@Value("value")
@Default
private @Meta double value = 0d;
@Override
public NoiseSampler get() {
return new ConstantSampler(value);
}
}

View File

@ -0,0 +1,97 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.Function;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.annotations.Value;
import com.dfsek.tectonic.exception.ValidationException;
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.templates.FunctionTemplate;
import com.dfsek.terra.addons.noise.config.templates.SamplerTemplate;
import com.dfsek.terra.addons.noise.paralithic.defined.UserDefinedFunction;
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2;
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
import com.dfsek.terra.addons.noise.samplers.noise.ExpressionFunction;
import com.dfsek.terra.api.config.meta.Meta;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings({ "FieldMayBeFinal", "unused" })
public class ExpressionFunctionTemplate extends SamplerTemplate<ExpressionFunction> {
private final Map<String, DimensionApplicableNoiseSampler> otherFunctions;
@Value("variables")
@Default
private @Meta Map<String, @Meta Double> vars = new HashMap<>();
@Value("expression")
private @Meta String equation;
@Value("samplers")
@Default
private @Meta LinkedHashMap<String, @Meta DimensionApplicableNoiseSampler> samplers = new LinkedHashMap<>();
@Value("functions")
@Default
private @Meta LinkedHashMap<String, @Meta FunctionTemplate> functions = new LinkedHashMap<>();
private final Map<String, FunctionTemplate> globalFunctions;
public ExpressionFunctionTemplate(Map<String, DimensionApplicableNoiseSampler> otherFunctions, Map<String, FunctionTemplate> samplers) {
this.otherFunctions = otherFunctions;
this.globalFunctions = samplers;
}
@Override
public NoiseSampler get() {
try {
Map<String, Function> noiseFunctionMap = generateFunctions();
return new ExpressionFunction(noiseFunctionMap, equation, vars);
} catch(ParseException e) {
throw new IllegalStateException(e);
}
}
@Override
public boolean validate() throws ValidationException {
try {
Map<String, Function> noiseFunctionMap = generateFunctions();
new ExpressionFunction(noiseFunctionMap, equation, vars);
} catch(ParseException e) {
throw new ValidationException("Errors occurred while parsing noise equation: ", e);
}
return super.validate();
}
private Map<String, Function> generateFunctions() throws ParseException {
Map<String, Function> noiseFunctionMap = new HashMap<>();
for(Map.Entry<String, FunctionTemplate> entry : globalFunctions.entrySet()) {
noiseFunctionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), new Parser(), new Scope()));
}
for(Map.Entry<String, FunctionTemplate> entry : functions.entrySet()) {
noiseFunctionMap.put(entry.getKey(), UserDefinedFunction.newInstance(entry.getValue(), new Parser(), new Scope()));
}
otherFunctions.forEach((id, function) -> {
if(function.getDimensions() == 2) {
noiseFunctionMap.put(id, new NoiseFunction2(function.getSampler()));
} else noiseFunctionMap.put(id, new NoiseFunction3(function.getSampler()));
});
samplers.forEach((id, function) -> {
if(function.getDimensions() == 2) {
noiseFunctionMap.put(id, new NoiseFunction2(function.getSampler()));
} else noiseFunctionMap.put(id, new NoiseFunction3(function.getSampler()));
});
return noiseFunctionMap;
}
}

View File

@ -0,0 +1,44 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.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;
public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
@Value("rotation")
@Default
private @Meta double rotation = 0.25;
@Value("isotropic")
@Default
private @Meta boolean isotropic = true;
@Value("deviation")
@Default
private @Meta double deviation = 1.0;
@Value("impulses")
@Default
private @Meta double impulses = 64d;
@Value("frequency_0")
@Default
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;
}
}

View File

@ -0,0 +1,20 @@
package com.dfsek.terra.addons.noise.config.templates.noise;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.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;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public abstract class NoiseTemplate<T extends NoiseFunction> extends SamplerTemplate<T> {
@Value("frequency")
@Default
protected @Meta double frequency = 0.02d;
@Value("salt")
@Default
protected @Meta long salt = 0;
}

View File

@ -0,0 +1,23 @@
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;
public class SimpleNoiseTemplate extends NoiseTemplate<NoiseFunction> {
private final Supplier<NoiseFunction> samplerSupplier;
public SimpleNoiseTemplate(Supplier<NoiseFunction> samplerSupplier) {
this.samplerSupplier = samplerSupplier;
}
@Override
public NoiseSampler get() {
NoiseFunction sampler = samplerSupplier.get();
sampler.setFrequency(frequency);
sampler.setSalt(salt);
return sampler;
}
}

View File

@ -0,0 +1,17 @@
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;
public class BrownianMotionTemplate extends FractalTemplate<BrownianMotionSampler> {
@Override
public NoiseSampler get() {
BrownianMotionSampler sampler = new BrownianMotionSampler(function);
sampler.setGain(fractalGain);
sampler.setLacunarity(fractalLacunarity);
sampler.setOctaves(octaves);
sampler.setWeightedStrength(weightedStrength);
return sampler;
}
}

View File

@ -0,0 +1,31 @@
package com.dfsek.terra.addons.noise.config.templates.noise.fractal;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.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;
public abstract class FractalTemplate<T extends FractalNoiseFunction> extends SamplerTemplate<T> {
@Value("octaves")
@Default
protected @Meta int octaves = 3;
@Value("gain")
@Default
protected @Meta double fractalGain = 0.5D;
@Value("lacunarity")
@Default
protected @Meta double fractalLacunarity = 2.0D;
@Value("weighted-strength")
@Default
protected @Meta double weightedStrength = 0.0D;
@Value("function")
protected @Meta NoiseSampler function;
}

View File

@ -0,0 +1,27 @@
package com.dfsek.terra.addons.noise.config.templates.noise.fractal;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.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;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class PingPongTemplate extends FractalTemplate<PingPongSampler> {
@Value("ping-pong")
@Default
private @Meta double pingPong = 2.0D;
@Override
public NoiseSampler get() {
PingPongSampler sampler = new PingPongSampler(function);
sampler.setGain(fractalGain);
sampler.setLacunarity(fractalLacunarity);
sampler.setOctaves(octaves);
sampler.setWeightedStrength(weightedStrength);
sampler.setPingPongStrength(pingPong);
return sampler;
}
}

View File

@ -0,0 +1,17 @@
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;
public class RidgedFractalTemplate extends FractalTemplate<RidgedFractalSampler> {
@Override
public NoiseSampler get() {
RidgedFractalSampler sampler = new RidgedFractalSampler(function);
sampler.setGain(fractalGain);
sampler.setLacunarity(fractalLacunarity);
sampler.setOctaves(octaves);
sampler.setWeightedStrength(weightedStrength);
return sampler;
}
}

View File

@ -0,0 +1,22 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.tectonic.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;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class ClampNormalizerTemplate extends NormalizerTemplate<ClampNormalizer> {
@Value("max")
private @Meta double max;
@Value("min")
private @Meta double min;
@Override
public NoiseSampler get() {
return new ClampNormalizer(function, min, max);
}
}

View File

@ -0,0 +1,22 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.tectonic.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;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class LinearNormalizerTemplate extends NormalizerTemplate<LinearNormalizer> {
@Value("max")
private @Meta double max;
@Value("min")
private @Meta double min;
@Override
public NoiseSampler get() {
return new LinearNormalizer(function, min, max);
}
}

View File

@ -0,0 +1,27 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.tectonic.annotations.Default;
import com.dfsek.tectonic.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;
@SuppressWarnings({ "unused", "FieldMayBeFinal" })
public class NormalNormalizerTemplate extends NormalizerTemplate<NormalNormalizer> {
@Value("mean")
private @Meta double mean;
@Value("standard-deviation")
private @Meta double stdDev;
@Value("groups")
@Default
private @Meta int groups = 16384;
@Override
public NoiseSampler get() {
return new NormalNormalizer(function, groups, mean, stdDev);
}
}

View File

@ -0,0 +1,14 @@
package com.dfsek.terra.addons.noise.config.templates.normalizer;
import com.dfsek.tectonic.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;
public abstract class NormalizerTemplate<T extends Normalizer> extends SamplerTemplate<T> {
@Value("function")
protected @Meta NoiseSampler function;
}

View File

@ -0,0 +1,22 @@
package com.dfsek.terra.addons.noise.normalizer;
import net.jafama.FastMath;
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 FastMath.max(FastMath.min(in, max), min);
}
}

View File

@ -0,0 +1,23 @@
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;
}
}

View File

@ -0,0 +1,47 @@
package com.dfsek.terra.addons.noise.normalizer;
import net.jafama.FastMath;
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 = FastMath.abs(lookup[start] - in);
double right = FastMath.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;
}
}

View File

@ -0,0 +1,24 @@
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 getNoiseSeeded(long seed, double x, double y) {
return normalize(sampler.getNoiseSeeded(seed, x, y));
}
@Override
public double getNoiseSeeded(long seed, double x, double y, double z) {
return normalize(sampler.getNoiseSeeded(seed, x, y, z));
}
}

View File

@ -0,0 +1,52 @@
package com.dfsek.terra.addons.noise.paralithic.defined;
import com.dfsek.paralithic.Expression;
import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.dynamic.Context;
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
import com.dfsek.paralithic.node.Statefulness;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
public class UserDefinedFunction implements DynamicFunction {
private final Expression expression;
private final int args;
protected UserDefinedFunction(Expression expression, int args) {
this.expression = expression;
this.args = args;
}
public static UserDefinedFunction newInstance(FunctionTemplate template, Parser parser, Scope parent) throws ParseException {
Scope functionScope = new Scope().withParent(parent);
template.getArgs().forEach(functionScope::addInvocationVariable);
return new UserDefinedFunction(parser.parse(template.getFunction(), functionScope), template.getArgs().size());
}
@Override
public double eval(double... args) {
return expression.evaluate(args);
}
@Override
public double eval(Context context, double... args) {
return expression.evaluate(context, args);
}
@Override
public int getArgNumber() {
return args;
}
@Override
public Statefulness statefulness() {
return Statefulness.STATELESS;
}
}

View File

@ -0,0 +1,37 @@
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.getNoiseSeeded(((SeedContext) context).getSeed(), args[0], args[1]);
}
@Override
public int getArgNumber() {
return 2;
}
@Override
public Statefulness statefulness() {
return Statefulness.CONTEXTUAL;
}
}

View File

@ -0,0 +1,37 @@
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.getNoiseSeeded(((SeedContext) context).getSeed(), args[0], args[1], args[2]);
}
@Override
public int getArgNumber() {
return 3;
}
@Override
public Statefulness statefulness() {
return Statefulness.CONTEXTUAL;
}
}

View File

@ -0,0 +1,16 @@
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;
}
}

View File

@ -0,0 +1,33 @@
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 getNoiseSeeded(long seed, double x, double y) {
return function.getNoiseSeeded(seed++,
x + warp.getNoiseSeeded(seed++, x, y) * amplitude,
y + warp.getNoiseSeeded(seed, x, y) * amplitude
);
}
@Override
public double getNoiseSeeded(long seed, double x, double y, double z) {
return function.getNoiseSeeded(seed++,
x + warp.getNoiseSeeded(seed++, x, y, z) * amplitude,
y + warp.getNoiseSeeded(seed++, x, y, z) * amplitude,
z + warp.getNoiseSeeded(seed, x, y, z) * amplitude
);
}
}

View File

@ -0,0 +1,68 @@
package com.dfsek.terra.addons.noise.samplers;
import net.jafama.FastMath;
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 getNoiseSeeded(long seed, double x, double y) {
return ((channel.getChannel(image.getRGB(FastMath.floorMod(FastMath.floorToInt(x * frequency), image.getWidth()),
FastMath.floorMod(FastMath.floorToInt(y * frequency), image.getHeight()))) / 255D) - 0.5) *
2;
}
@Override
public double getNoiseSeeded(long seed, double x, double y, double z) {
return getNoiseSeeded(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);
}
}

View File

@ -0,0 +1,50 @@
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 getNoiseSeeded(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++) {
accumulator += in.getNoiseSeeded(seed, x + kx, y + ky) * kernel[kx][ky];
}
}
return accumulator;
}
@Override
public double getNoiseSeeded(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++) {
accumulator += in.getNoiseSeeded(seed, x + kx, y, z + ky) * kernel[kx][ky];
}
}
return accumulator;
}
}

View File

@ -0,0 +1,537 @@
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;
import com.dfsek.terra.api.util.vector.Vector2;
import com.dfsek.terra.api.util.vector.Vector3;
/**
* 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;
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;
}
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int xr = fastRound(x);
int yr = fastRound(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;
Vector2 center = new Vector2(x, y);
switch(distanceFunction) {
default:
case Euclidean:
case EuclideanSq:
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 = vecX * vecX + vecY * vecY;
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
center.setZ((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;
}
break;
case Manhattan:
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 = fastAbs(vecX) + fastAbs(vecY);
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
center.setZ((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;
}
break;
case Hybrid:
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 = (fastAbs(vecX) + fastAbs(vecY)) + (vecX * vecX + vecY * vecY);
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_2D[idx] * cellularJitter) / frequency);
center.setZ((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;
}
break;
}
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
distance0 = fastSqrt(distance0);
if(returnType != ReturnType.CellValue) {
distance1 = fastSqrt(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.getNoiseSeeded(sl, center.getX(), center.getZ());
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;
};
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int xr = fastRound(x);
int yr = fastRound(y);
int zr = fastRound(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;
Vector3 center = new Vector3(x, y, z);
switch(distanceFunction) {
case Euclidean:
case EuclideanSq:
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 = vecX * vecX + vecY * vecY + vecZ * vecZ;
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
center.setY((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
center.setZ((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;
}
break;
case Manhattan:
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 = fastAbs(vecX) + fastAbs(vecY) + fastAbs(vecZ);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
center.setY((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
center.setZ((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;
}
break;
case Hybrid:
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 = (fastAbs(vecX) + fastAbs(vecY) + fastAbs(vecZ)) +
(vecX * vecX + vecY * vecY + vecZ * vecZ);
distance1 = fastMax(fastMin(distance1, newDistance), distance0);
if(newDistance < distance0) {
distance0 = newDistance;
closestHash = hash;
center.setX((xi + RAND_VECS_3D[idx] * cellularJitter) / frequency);
center.setY((yi + RAND_VECS_3D[idx | 1] * cellularJitter) / frequency);
center.setZ((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;
}
break;
default:
break;
}
if(distanceFunction == DistanceFunction.Euclidean && returnType != ReturnType.CellValue) {
distance0 = fastSqrt(distance0);
if(returnType != ReturnType.CellValue) {
distance1 = fastSqrt(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.getNoiseSeeded(sl, center.getX(), center.getY(), center.getZ());
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;
};
}
public enum DistanceFunction {
Euclidean,
EuclideanSq,
Manhattan,
Hybrid
}
public enum ReturnType {
CellValue,
Distance,
Distance2,
Distance2Add,
Distance2Sub,
Distance2Mul,
Distance2Div,
NoiseLookup,
Distance3,
Distance3Add,
Distance3Sub,
Distance3Mul,
Distance3Div
}
}

View File

@ -0,0 +1,22 @@
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;
}
}

View File

@ -0,0 +1,45 @@
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.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) throws ParseException {
Parser p = new Parser();
Scope scope = new Scope();
scope.addInvocationVariable("x");
scope.addInvocationVariable("y");
scope.addInvocationVariable("z");
vars.forEach(scope::create);
functions.forEach(p::registerFunction);
expression = p.parse(eq, scope);
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);
}
}

View File

@ -0,0 +1,107 @@
package com.dfsek.terra.addons.noise.samplers.noise;
import net.jafama.FastMath;
import com.dfsek.terra.addons.noise.samplers.noise.random.WhiteNoiseSampler;
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 = (FastMath.sqrt(-FastMath.log(0.05) / Math.PI) / a);
private double omega0 = Math.PI * 0.25;
private boolean isotropic = true;
private double impulsesPerKernel = 64d;
private double impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius));
private double impulsesPerCell = impulseDensity * kernelRadius * kernelRadius;
private double g = FastMath.exp(-impulsesPerCell);
public GaborNoiseSampler() {
rand = new WhiteNoiseSampler();
}
private void recalculateRadiusAndDensity() {
kernelRadius = (FastMath.sqrt(-FastMath.log(0.05) / Math.PI) / this.a);
impulseDensity = (impulsesPerKernel / (Math.PI * kernelRadius * kernelRadius));
impulsesPerCell = impulseDensity * kernelRadius * kernelRadius;
g = FastMath.exp(-impulsesPerCell);
}
private double gaborNoise(long seed, double x, double y) {
x /= kernelRadius;
y /= kernelRadius;
int xi = fastFloor(x);
int yi = fastFloor(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 = 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 * (FastMath.exp(-Math.PI * (a * a) * (x * x + y * y)) * fastCos(2 * Math.PI * f0 * (x * fastCos(omega_0) + y * fastSin(
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);
}
}

View File

@ -0,0 +1,143 @@
package com.dfsek.terra.addons.noise.samplers.noise;
import net.jafama.FastMath;
import com.dfsek.terra.api.noise.NoiseSampler;
@SuppressWarnings("ManualMinMaxCalculation")
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;
static final int precision = 100;
static final int modulus = 360 * precision;
static final double[] sin = new double[360 * 100]; // lookup table
static {
for(int i = 0; i < sin.length; i++) {
sin[i] = (float) Math.sin((double) (i) / (precision));
}
}
protected double frequency = 0.02d;
protected long salt;
public NoiseFunction() {
this.salt = 0;
}
protected static int fastFloor(double f) {
return f >= 0 ? (int) f : (int) f - 1;
}
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;
}
protected static int fastRound(double f) {
return f >= 0 ? (int) (f + 0.5f) : (int) (f - 0.5);
}
protected static double lerp(double a, double b, double t) {
return a + t * (b - a);
}
protected static double interpHermite(double t) {
return t * t * (3 - 2 * t);
}
protected static double interpQuintic(double t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
protected static double cubicLerp(double a, double b, double c, double d, double t) {
double p = (d - c) - (a - b);
return t * t * t * p + t * t * ((a - b) - p) + t * (c - a) + b;
}
protected static double fastMin(double a, double b) {
return a < b ? a : b;
}
protected static double fastMax(double a, double b) {
return a > b ? a : b;
}
protected static double fastAbs(double f) {
return f < 0 ? -f : f;
}
protected static double fastSqrt(double f) {
return FastMath.sqrt(f);
}
protected static int fastCeil(double f) {
int i = (int) f;
if(i < f) i++;
return i;
}
/**
* Murmur64 hashing function
*
* @param h Input value
*
* @return Hashed value
*/
protected static long murmur64(long h) {
h ^= h >>> 33;
h *= 0xff51afd7ed558ccdL;
h ^= h >>> 33;
h *= 0xc4ceb9fe1a85ec53L;
h ^= h >>> 33;
return h;
}
protected static double fastSin(double a) {
return sinLookup((int) (a * precision + 0.5f));
}
protected static double fastCos(double a) {
return sinLookup((int) ((a + Math.PI / 2) * precision + 0.5f));
}
private static double sinLookup(int a) {
return a >= 0 ? sin[a % (modulus)] : -sin[-a % (modulus)];
}
public void setSalt(long salt) {
this.salt = salt;
}
public double getFrequency() {
return frequency;
}
public void setFrequency(double frequency) {
this.frequency = frequency;
}
@Override
public double getNoiseSeeded(long seed, double x, double y) {
return getNoiseRaw(seed + salt, x * frequency, y * frequency);
}
@Override
public double getNoiseSeeded(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);
}

View File

@ -0,0 +1,47 @@
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
import com.dfsek.terra.api.noise.NoiseSampler;
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.getNoiseSeeded(seed++, x, y);
sum += noise * amp;
amp *= lerp(1.0, fastMin(noise + 1, 2) * 0.5, weightedStrength);
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.getNoiseSeeded(seed++, x, y, z);
sum += noise * amp;
amp *= lerp(1.0, (noise + 1) * 0.5, weightedStrength);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
}

View File

@ -0,0 +1,48 @@
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
import com.dfsek.terra.api.noise.NoiseSampler;
public abstract class FractalNoiseFunction extends NoiseFunction {
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 = fastAbs(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;
}
}

View File

@ -0,0 +1,59 @@
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
import com.dfsek.terra.api.noise.NoiseSampler;
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.getNoiseSeeded(seed++, x, y) + 1) * pingPongStrength);
sum += (noise - 0.5) * 2 * amp;
amp *= lerp(1.0, noise, weightedStrength);
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.getNoiseSeeded(seed++, x, y, z) + 1) * pingPongStrength);
sum += (noise - 0.5) * 2 * amp;
amp *= lerp(1.0, noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
}

View File

@ -0,0 +1,48 @@
package com.dfsek.terra.addons.noise.samplers.noise.fractal;
import com.dfsek.terra.api.noise.NoiseSampler;
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 = fastAbs(input.getNoiseSeeded(seed++, x, y));
sum += (noise * -2 + 1) * amp;
amp *= lerp(1.0, 1 - noise, weightedStrength);
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 = fastAbs(input.getNoiseSeeded(seed++, x, y, z));
sum += (noise * -2 + 1) * amp;
amp *= lerp(1.0, 1 - noise, weightedStrength);
x *= lacunarity;
y *= lacunarity;
z *= lacunarity;
amp *= gain;
}
return sum;
}
}

View File

@ -0,0 +1,39 @@
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.getNoiseSeeded(seed++, x, y);
v2 = whiteNoiseSampler.getNoiseSeeded(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.getNoiseSeeded(seed++, x, y, z);
v2 = whiteNoiseSampler.getNoiseSeeded(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;
}
}

View File

@ -0,0 +1,53 @@
package com.dfsek.terra.addons.noise.samplers.noise.random;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
/**
* 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 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 murmur64(hash);
}
public double getNoiseRaw(long seed) {
return (Double.longBitsToDouble((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);
}
}

View File

@ -0,0 +1,272 @@
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 = fastFloor(x);
int j = fastFloor(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 = fastFloor(x);
int j = fastFloor(y);
int k = fastFloor(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;
}
}

View File

@ -0,0 +1,153 @@
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 = fastFloor(x);
int j = fastFloor(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 n0, n1, n2;
double a = 0.5 - x0 * x0 - y0 * y0;
if(a <= 0) n0 = 0;
else {
n0 = (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) n2 = 0;
else {
double x2 = x0 + (2 * G2 - 1);
double y2 = y0 + (2 * G2 - 1);
n2 = (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) n1 = 0;
else {
n1 = (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) n1 = 0;
else {
n1 = (b * b) * (b * b) * gradCoord(seed, i + PRIME_X, j, x1, y1);
}
}
return (n0 + n1 + n2) * 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 = fastRound(x);
int j = fastRound(y);
int k = fastRound(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;
}
}

View File

@ -0,0 +1,67 @@
package com.dfsek.terra.addons.noise.samplers.noise.simplex;
/**
* 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 = fastFloor(x);
int y0 = fastFloor(y);
double xd0 = x - x0;
double yd0 = y - y0;
double xd1 = xd0 - 1;
double yd1 = yd0 - 1;
double xs = interpQuintic(xd0);
double ys = interpQuintic(yd0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
int x1 = x0 + PRIME_X;
int y1 = y0 + PRIME_Y;
double xf0 = lerp(gradCoord(seed, x0, y0, xd0, yd0), gradCoord(seed, x1, y0, xd1, yd0), xs);
double xf1 = lerp(gradCoord(seed, x0, y1, xd0, yd1), gradCoord(seed, x1, y1, xd1, yd1), xs);
return lerp(xf0, xf1, ys) * 1.4247691104677813;
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x0 = fastFloor(x);
int y0 = fastFloor(y);
int z0 = fastFloor(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 = interpQuintic(xd0);
double ys = interpQuintic(yd0);
double zs = 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 = lerp(gradCoord(seed, x0, y0, z0, xd0, yd0, zd0), gradCoord(seed, x1, y0, z0, xd1, yd0, zd0), xs);
double xf10 = lerp(gradCoord(seed, x0, y1, z0, xd0, yd1, zd0), gradCoord(seed, x1, y1, z0, xd1, yd1, zd0), xs);
double xf01 = lerp(gradCoord(seed, x0, y0, z1, xd0, yd0, zd1), gradCoord(seed, x1, y0, z1, xd1, yd0, zd1), xs);
double xf11 = lerp(gradCoord(seed, x0, y1, z1, xd0, yd1, zd1), gradCoord(seed, x1, y1, z1, xd1, yd1, zd1), xs);
double yf0 = lerp(xf00, xf10, ys);
double yf1 = lerp(xf01, xf11, ys);
return lerp(yf0, yf1, zs) * 0.964921414852142333984375;
}
}

View File

@ -0,0 +1,242 @@
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 = fastFloor(x + t);
int j = fastFloor(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 = fastFloor(x + t);
int j = fastFloor(y + t);
int k = fastFloor(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;
}
}
}

View File

@ -0,0 +1,97 @@
package com.dfsek.terra.addons.noise.samplers.noise.simplex;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
/**
* Abstract NoiseSampler implementation for simplex-style noise functions.
*/
public abstract class SimplexStyleSampler extends NoiseFunction {
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 double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) {
int hash = hash(seed, xPrimed, yPrimed);
hash ^= hash >> 15;
hash &= 127 << 1;
double xg = GRADIENTS_2_D[hash];
double yg = GRADIENTS_2_D[hash | 1];
return xd * xg + yd * yg;
}
protected static double gradCoord(int seed, int xPrimed, int yPrimed, int zPrimed, double xd, double yd, double zd) {
int hash = hash(seed, xPrimed, yPrimed, zPrimed);
hash ^= hash >> 15;
hash &= 63 << 2;
double xg = GRADIENTS_3D[hash];
double yg = GRADIENTS_3D[hash | 1];
double zg = GRADIENTS_3D[hash | 2];
return xd * xg + yd * yg + zd * zg;
}
}

View File

@ -0,0 +1,102 @@
package com.dfsek.terra.addons.noise.samplers.noise.value;
public class ValueCubicSampler extends ValueStyleNoise {
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x1 = fastFloor(x);
int y1 = fastFloor(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 cubicLerp(
cubicLerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), valCoord(seed, x2, y0), valCoord(seed, x3, y0),
xs),
cubicLerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), valCoord(seed, x2, y1), valCoord(seed, x3, y1),
xs),
cubicLerp(valCoord(seed, x0, y2), valCoord(seed, x1, y2), valCoord(seed, x2, y2), valCoord(seed, x3, y2),
xs),
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 = fastFloor(x);
int y1 = fastFloor(y);
int z1 = fastFloor(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 cubicLerp(
cubicLerp(
cubicLerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), valCoord(seed, x2, y0, z0),
valCoord(seed, x3, y0, z0), xs),
cubicLerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), valCoord(seed, x2, y1, z0),
valCoord(seed, x3, y1, z0), xs),
cubicLerp(valCoord(seed, x0, y2, z0), valCoord(seed, x1, y2, z0), valCoord(seed, x2, y2, z0),
valCoord(seed, x3, y2, z0), xs),
cubicLerp(valCoord(seed, x0, y3, z0), valCoord(seed, x1, y3, z0), valCoord(seed, x2, y3, z0),
valCoord(seed, x3, y3, z0), xs),
ys),
cubicLerp(
cubicLerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), valCoord(seed, x2, y0, z1),
valCoord(seed, x3, y0, z1), xs),
cubicLerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), valCoord(seed, x2, y1, z1),
valCoord(seed, x3, y1, z1), xs),
cubicLerp(valCoord(seed, x0, y2, z1), valCoord(seed, x1, y2, z1), valCoord(seed, x2, y2, z1),
valCoord(seed, x3, y2, z1), xs),
cubicLerp(valCoord(seed, x0, y3, z1), valCoord(seed, x1, y3, z1), valCoord(seed, x2, y3, z1),
valCoord(seed, x3, y3, z1), xs),
ys),
cubicLerp(
cubicLerp(valCoord(seed, x0, y0, z2), valCoord(seed, x1, y0, z2), valCoord(seed, x2, y0, z2),
valCoord(seed, x3, y0, z2), xs),
cubicLerp(valCoord(seed, x0, y1, z2), valCoord(seed, x1, y1, z2), valCoord(seed, x2, y1, z2),
valCoord(seed, x3, y1, z2), xs),
cubicLerp(valCoord(seed, x0, y2, z2), valCoord(seed, x1, y2, z2), valCoord(seed, x2, y2, z2),
valCoord(seed, x3, y2, z2), xs),
cubicLerp(valCoord(seed, x0, y3, z2), valCoord(seed, x1, y3, z2), valCoord(seed, x2, y3, z2),
valCoord(seed, x3, y3, z2), xs),
ys),
cubicLerp(
cubicLerp(valCoord(seed, x0, y0, z3), valCoord(seed, x1, y0, z3), valCoord(seed, x2, y0, z3),
valCoord(seed, x3, y0, z3), xs),
cubicLerp(valCoord(seed, x0, y1, z3), valCoord(seed, x1, y1, z3), valCoord(seed, x2, y1, z3),
valCoord(seed, x3, y1, z3), xs),
cubicLerp(valCoord(seed, x0, y2, z3), valCoord(seed, x1, y2, z3), valCoord(seed, x2, y2, z3),
valCoord(seed, x3, y2, z3), xs),
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));
}
}

View File

@ -0,0 +1,52 @@
package com.dfsek.terra.addons.noise.samplers.noise.value;
public class ValueSampler extends ValueStyleNoise {
@Override
public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x0 = fastFloor(x);
int y0 = fastFloor(y);
double xs = interpHermite(x - x0);
double ys = interpHermite(y - y0);
x0 *= PRIME_X;
y0 *= PRIME_Y;
int x1 = x0 + PRIME_X;
int y1 = y0 + PRIME_Y;
double xf0 = lerp(valCoord(seed, x0, y0), valCoord(seed, x1, y0), xs);
double xf1 = lerp(valCoord(seed, x0, y1), valCoord(seed, x1, y1), xs);
return lerp(xf0, xf1, ys);
}
@Override
public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x0 = fastFloor(x);
int y0 = fastFloor(y);
int z0 = fastFloor(z);
double xs = interpHermite(x - x0);
double ys = interpHermite(y - y0);
double zs = 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 = lerp(valCoord(seed, x0, y0, z0), valCoord(seed, x1, y0, z0), xs);
double xf10 = lerp(valCoord(seed, x0, y1, z0), valCoord(seed, x1, y1, z0), xs);
double xf01 = lerp(valCoord(seed, x0, y0, z1), valCoord(seed, x1, y0, z1), xs);
double xf11 = lerp(valCoord(seed, x0, y1, z1), valCoord(seed, x1, y1, z1), xs);
double yf0 = lerp(xf00, xf10, ys);
double yf1 = lerp(xf01, xf11, ys);
return lerp(yf0, yf1, zs);
}
}

View File

@ -0,0 +1,23 @@
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);
}
}

View File

@ -0,0 +1,119 @@
/*
Copyright 2009 Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
retains certain rights in this software.
BSD Open Source License.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Sandia National Laboratories nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
package com.dfsek.terra.addons.noise.util;
import java.io.Serializable;
public abstract class HashIntrinsic implements Serializable {
public static final int FLOAT_EXP_BIT_MASK = 2139095040;
public static final int FLOAT_SIGNIF_BIT_MASK = 8388607;
public static final long DOUBLE_EXP_BIT_MASK = 9218868437227405312L;
public static final long DOUBLE_SIGNIF_BIT_MASK = 4503599627370495L;
protected static final int DEFAULT_INITIAL_CAPACITY = 16;
protected static final int MAXIMUM_CAPACITY = 1073741824;
protected static final float DEFAULT_LOAD_FACTOR = 0.75F;
private static final long serialVersionUID = 8058099372006904458L;
protected int size;
protected int threshold;
protected float loadFactor;
protected int capMinus1;
protected HashIntrinsic(int initialCapacity, float loadFactor) {
if(initialCapacity <= 0) {
throw new IllegalArgumentException("Illegal initial capacity: " + initialCapacity);
} else if(!(loadFactor <= 0.0F) && !Float.isNaN(loadFactor)) {
if(initialCapacity > 1073741824) {
initialCapacity = 1073741824;
}
int capacity;
for(capacity = 1; capacity < initialCapacity; capacity <<= 1) {
}
this.capMinus1 = capacity - 1;
this.loadFactor = loadFactor;
this.threshold = (int) ((float) capacity * loadFactor);
} else {
throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
}
}
public static int floatToIntBits(float value) {
int result = Float.floatToRawIntBits(value);
if((result & 2139095040) == 2139095040 && (result & 8388607) != 0) {
result = 2143289344;
}
return result;
}
public static long doubleToLongBits(double value) {
long result = Double.doubleToRawLongBits(value);
if((result & 9218868437227405312L) == 9218868437227405312L && (result & 4503599627370495L) != 0L) {
result = 9221120237041090560L;
}
return result;
}
protected static int hashCodeLong(long value) {
return (int) (value ^ value >>> 32);
}
protected static int hashCodeFloat(float value) {
return floatToIntBits(value);
}
protected static int hashCodeDouble(double value) {
long bits = doubleToLongBits(value);
return (int) (bits ^ bits >>> 32);
}
protected static int tableIndex(int hc, int lm1) {
hc ^= hc >>> 20 ^ hc >>> 12;
hc ^= hc >>> 7 ^ hc >>> 4;
return hc & lm1;
}
public int size() {
return this.size;
}
public abstract void clear();
public boolean isEmpty() {
return this.size == 0;
}
}

View File

@ -0,0 +1,295 @@
/*
Copyright 2009 Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
retains certain rights in this software.
BSD Open Source License.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Sandia National Laboratories nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
package com.dfsek.terra.addons.noise.util;
import java.io.Serializable;
import java.util.Arrays;
import java.util.NoSuchElementException;
public class HashMapDoubleDouble extends HashIntrinsic {
private static final long serialVersionUID = 2109458761298324234L;
private HashMapDoubleDouble.Entry[] table;
public HashMapDoubleDouble(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor);
this.table = this.createTable(this.capMinus1 + 1);
}
public HashMapDoubleDouble(int initialCapacity) {
this(initialCapacity, 0.75F);
}
public HashMapDoubleDouble() {
this(16, 0.75F);
}
public final boolean contains(double key) {
int i = tableIndex(hashCodeDouble(key), this.capMinus1);
for(HashMapDoubleDouble.Entry e = this.table[i]; e != null; e = e.next) {
if(e.key == key) {
return true;
}
}
return false;
}
public boolean containsValue(double value) {
for(Entry entry : this.table) {
for(Entry e = entry; e != null; e = e.next) {
if(value == e.value) {
return true;
}
}
}
return false;
}
public double get(double key) {
int i = tableIndex(hashCodeDouble(key), this.capMinus1);
for(HashMapDoubleDouble.Entry e = this.table[i]; e != null; e = e.next) {
if(key == e.key) {
return e.value;
}
}
return 4.9E-324D;
}
public double put(double key, double value) {
int i = tableIndex(hashCodeDouble(key), this.capMinus1);
for(HashMapDoubleDouble.Entry e = this.table[i]; e != null; e = e.next) {
if(key == e.key) {
double oldValue = e.value;
e.value = value;
return oldValue;
}
}
this.addEntry(key, value, i);
return 4.9E-324D;
}
public void resize(int newCapacity) {
int oldCapacity = this.table.length;
if(oldCapacity == 1073741824) {
this.threshold = 2147483647;
} else {
HashMapDoubleDouble.Entry[] newTable = this.createTable(newCapacity);
this.capMinus1 = newCapacity - 1;
this.transfer(newTable);
this.table = newTable;
this.threshold = (int) ((float) newCapacity * this.loadFactor);
}
}
public final HashMapDoubleDouble.Entry remove(double key) {
int i = tableIndex(hashCodeDouble(key), this.capMinus1);
HashMapDoubleDouble.Entry prev = this.table[i];
HashMapDoubleDouble.Entry e;
HashMapDoubleDouble.Entry next;
for(e = prev; e != null; e = next) {
next = e.next;
if(key == e.key) {
--this.size;
if(prev == e) {
this.table[i] = next;
} else {
prev.next = next;
}
return e;
}
prev = e;
}
return e;
}
public void clear() {
Arrays.fill(this.table, null);
this.size = 0;
}
public long memoryEstimate(int ptrsize) {
return (long) ptrsize * (long) (this.capMinus1 + this.size + 1) + (this.size * 64L / 4);
}
public HashMapDoubleDouble.Iterator iterator() {
return new HashMapDoubleDouble.Iterator();
}
private void addEntry(double key, double value, int index) {
HashMapDoubleDouble.Entry e = this.table[index];
this.table[index] = new HashMapDoubleDouble.Entry(key, value, e);
if(this.size++ >= this.threshold) {
this.resize(2 * this.table.length);
}
}
private void transfer(HashMapDoubleDouble.Entry[] newTable) {
for(int j = 0; j < this.table.length; ++j) {
HashMapDoubleDouble.Entry e = this.table[j];
if(e != null) {
this.table[j] = null;
HashMapDoubleDouble.Entry next;
do {
next = e.next;
int i = tableIndex(hashCodeDouble(e.key), this.capMinus1);
e.next = newTable[i];
newTable[i] = e;
e = next;
} while(next != null);
}
}
}
private HashMapDoubleDouble.Entry[] createTable(int capacity) {
return new HashMapDoubleDouble.Entry[capacity];
}
public HashMapDoubleDouble.Entry getEntry(double key) {
int i = tableIndex(hashCodeDouble(key), this.capMinus1);
for(HashMapDoubleDouble.Entry e = this.table[i]; e != null; e = e.next) {
if(key == e.key) {
return e;
}
}
return null;
}
public static class Entry implements Serializable {
private static final long serialVersionUID = 7972173983741231238L;
private final double key;
private double value;
private HashMapDoubleDouble.Entry next;
public Entry(double key, double val, HashMapDoubleDouble.Entry n) {
this.key = key;
this.value = val;
this.next = n;
}
public final double setValue(double newValue) {
double oldValue = this.value;
this.value = newValue;
return oldValue;
}
public final double getKey() {
return this.key;
}
public final double getValue() {
return this.value;
}
public final int hashCode() {
return hashCodeDouble(key) + hashCodeDouble(value);
}
public final boolean equals(Object o) {
HashMapDoubleDouble.Entry e = (HashMapDoubleDouble.Entry) o;
return this.key == e.key && this.value == e.value;
}
public final String toString() {
return this.key + " = " + this.value;
}
}
public class Iterator {
HashMapDoubleDouble.Entry next;
int index;
HashMapDoubleDouble.Entry current;
Iterator() {
if(HashMapDoubleDouble.this.size > 0) {
while(this.index < HashMapDoubleDouble.this.table.length &&
(this.next = HashMapDoubleDouble.this.table[this.index++]) == null) {
}
}
}
public HashMapDoubleDouble.Entry nextEntry() {
HashMapDoubleDouble.Entry e = this.next;
if(e == null) {
throw new NoSuchElementException();
} else {
if((this.next = e.next) == null) {
while(this.index < HashMapDoubleDouble.this.table.length &&
(this.next = HashMapDoubleDouble.this.table[this.index++]) == null) {
}
}
this.current = e;
return e;
}
}
public double next() {
return this.nextEntry().value;
}
public void remove() {
if(this.current == null) {
throw new IllegalStateException();
} else {
double k = this.current.key;
this.current = null;
HashMapDoubleDouble.this.remove(k);
}
}
public final boolean hasNext() {
return this.next != null;
}
}
}