mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-27 06:20:02 +00:00
Refined existing noise
- Hexagon styles produce coherent solid cells with contained subdivisions - Sierpinski triangles use equilateral recursive geometry - Noise styles share a 64-block base scale - Zoom scales the complete pattern with its distortion - Octaves preserve the base seed and feature scale - Coordinate dispatch uses the native dimensional sampler - Classic kernels retain seed precision and bounded output - Interpolation preserves fractional coordinates and symmetric curves - Noise caches respect sampling bounds and generation identity - Clover sampling reuses vertices and cached trigonometry - Noise and terrain tests cover corrected sampling behavior
This commit is contained in:
1 parent
f2887632fe
commit
50894b90ce
47 files changed
+2603
-1542
No files matched your search
@@ -21,6 +21,7 @@ package art.arcane.iris.engine.object;
|
||||
import art.arcane.iris.core.loader.IrisData;
|
||||
import art.arcane.iris.engine.data.cache.LazyBoundedCache;
|
||||
import art.arcane.iris.engine.framework.Engine;
|
||||
import art.arcane.iris.engine.history.GenerationKernelRegistry;
|
||||
import art.arcane.iris.engine.object.annotations.Desc;
|
||||
import art.arcane.iris.engine.object.annotations.MaxNumber;
|
||||
import art.arcane.iris.engine.object.annotations.MinNumber;
|
||||
@@ -40,6 +41,7 @@ import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -65,7 +67,7 @@ public class IrisGeneratorStyle {
|
||||
@Desc("Cell zooms")
|
||||
private double cellularZoom = 1;
|
||||
@MinNumber(0.00001)
|
||||
@Desc("The zoom of this style")
|
||||
@Desc("Feature size multiplier. Built-in coherent noise uses a 64-block base scale; 2 doubles feature size.")
|
||||
private double zoom = 1;
|
||||
@Desc("Instead of using the style property, use a custom expression to represent this style.")
|
||||
@RegistryListResource(IrisExpression.class)
|
||||
@@ -97,11 +99,15 @@ public class IrisGeneratorStyle {
|
||||
}
|
||||
|
||||
public CNG createNoCache(RNG rng, IrisData data) {
|
||||
return createNoCache(rng, data, false, 0, false, resolveEngine(data));
|
||||
return createNoCache(rng, data, 1, 0, false, resolveEngine(data));
|
||||
}
|
||||
|
||||
public CNG createForLayer(RNG rng, IrisData data, int octaveMultiplier) {
|
||||
return createNoCache(rng, data, Math.clamp(octaveMultiplier, 1, 16), 0, false, resolveEngine(data));
|
||||
}
|
||||
|
||||
public CNG createForPrebake(RNG rng, IrisData data, int fallbackCacheSize) {
|
||||
return createNoCache(rng, data, false, Math.max(0, fallbackCacheSize), true, resolveEngine(data));
|
||||
return createNoCache(rng, data, 1, Math.max(0, fallbackCacheSize), true, resolveEngine(data));
|
||||
}
|
||||
|
||||
|
||||
@@ -121,16 +127,17 @@ public class IrisGeneratorStyle {
|
||||
return hash();
|
||||
}
|
||||
|
||||
private String cachePrefix(RNG rng, int effectiveCacheSize, long engineStamp) {
|
||||
return "style-" + Integer.toUnsignedString(hash())
|
||||
private String cachePrefix(RNG rng, int effectiveCacheSize, long engineStamp, int octaveMultiplier) {
|
||||
return "noise-" + NoiseCacheIdentity.FINGERPRINT + "-style-" + Integer.toUnsignedString(hash())
|
||||
+ "-seed-" + Long.toUnsignedString(rng.getSeed())
|
||||
+ "-eng-" + Long.toUnsignedString(engineStamp)
|
||||
+ "-oct-" + octaveMultiplier
|
||||
+ "-sz-" + effectiveCacheSize
|
||||
+ "-src-";
|
||||
}
|
||||
|
||||
private String cacheKey(RNG rng, long sourceStamp, int effectiveCacheSize, long engineStamp) {
|
||||
return cachePrefix(rng, effectiveCacheSize, engineStamp) + Long.toUnsignedString(sourceStamp);
|
||||
private String cacheKey(RNG rng, long sourceStamp, int effectiveCacheSize, long engineStamp, int octaveMultiplier) {
|
||||
return cachePrefix(rng, effectiveCacheSize, engineStamp, octaveMultiplier) + Long.toUnsignedString(sourceStamp);
|
||||
}
|
||||
|
||||
private void clearStaleCacheEntries(IrisData data, String prefix, String key) {
|
||||
@@ -157,12 +164,19 @@ public class IrisGeneratorStyle {
|
||||
}
|
||||
}
|
||||
|
||||
public CNG createNoCache(RNG rng, IrisData data, boolean actuallyCached) {
|
||||
return createNoCache(rng, data, actuallyCached, 0, false, resolveEngine(data));
|
||||
}
|
||||
|
||||
private CNG createNoCache(RNG rng, IrisData data, boolean actuallyCached, int fallbackCacheSize,
|
||||
private CNG createNoCache(RNG rng, IrisData data, int octaveMultiplier, int fallbackCacheSize,
|
||||
boolean quietCacheLog, Engine engine) {
|
||||
requirePositiveFinite("zoom", zoom);
|
||||
requirePositiveFinite("exponent", exponent);
|
||||
if (!Double.isFinite(cellularFrequency) || cellularFrequency < 0D) {
|
||||
throw new IllegalArgumentException("cellularFrequency must be finite and nonnegative");
|
||||
}
|
||||
if (cellularFrequency > 0D) {
|
||||
requirePositiveFinite("cellularZoom", cellularZoom);
|
||||
}
|
||||
if (fracture != null) {
|
||||
requirePositiveFinite("fracture.multiplier", fracture.getMultiplier());
|
||||
}
|
||||
CNG cng = null;
|
||||
long sourceStamp = 0L;
|
||||
if (getExpression() != null) {
|
||||
@@ -182,10 +196,11 @@ public class IrisGeneratorStyle {
|
||||
cng = (style != null ? style : NoiseStyle.FLAT).create(rng).bake();
|
||||
}
|
||||
|
||||
cng = cng.scale(1D / zoom).pow(exponent).bake();
|
||||
cng = cng.oct(Math.clamp((long) cng.getOct() * octaveMultiplier, 1, 16))
|
||||
.pow(cng.getPower() * exponent);
|
||||
|
||||
if (fracture != null) {
|
||||
cng.fractureWith(fracture.createNoCache(rng.nextParallelRNG(2934), data, false,
|
||||
cng.fractureWith(fracture.createNoCache(rng.nextParallelRNG(2934), data, 1,
|
||||
fallbackCacheSize, quietCacheLog, engine), fracture.getMultiplier());
|
||||
}
|
||||
|
||||
@@ -193,11 +208,13 @@ public class IrisGeneratorStyle {
|
||||
cng = cng.cellularize(rng.nextParallelRNG(884466), cellularFrequency).scale(1D / cellularZoom).bake();
|
||||
}
|
||||
|
||||
cng.zoom(zoom);
|
||||
|
||||
int effectiveCacheSize = cacheSize > 0 ? cacheSize : Math.max(0, fallbackCacheSize);
|
||||
if (effectiveCacheSize > 0) {
|
||||
long engineStamp = engineStamp(engine);
|
||||
String key = cacheKey(rng, sourceStamp, effectiveCacheSize, engineStamp);
|
||||
clearStaleCacheEntries(data, cachePrefix(rng, effectiveCacheSize, engineStamp), key);
|
||||
String key = cacheKey(rng, sourceStamp, effectiveCacheSize, engineStamp, octaveMultiplier);
|
||||
clearStaleCacheEntries(data, cachePrefix(rng, effectiveCacheSize, engineStamp, octaveMultiplier), key);
|
||||
cng = cng.cached(effectiveCacheSize, key, data.getDataFolder(), quietCacheLog);
|
||||
}
|
||||
|
||||
@@ -215,7 +232,7 @@ public class IrisGeneratorStyle {
|
||||
public CNG create(RNG rng, IrisData data, Engine engine) {
|
||||
GeneratorCacheKey key = new GeneratorCacheKey(data, engine, rng.getSeed());
|
||||
return generatorCache.computeIfAbsent(key,
|
||||
ignored -> createNoCache(rng, data, true, 0, false, engine));
|
||||
ignored -> createNoCache(rng, data, 1, 0, false, engine));
|
||||
}
|
||||
|
||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
||||
@@ -244,6 +261,25 @@ public class IrisGeneratorStyle {
|
||||
return data == null ? null : data.getEngine();
|
||||
}
|
||||
|
||||
private static void requirePositiveFinite(String field, double value) {
|
||||
if (!Double.isFinite(value) || value <= 0D || !Double.isFinite(1D / value)) {
|
||||
throw new IllegalArgumentException(field + " must be finite and positive");
|
||||
}
|
||||
}
|
||||
|
||||
private static final class NoiseCacheIdentity {
|
||||
private static final String FINGERPRINT = fingerprint();
|
||||
|
||||
private static String fingerprint() {
|
||||
GenerationKernelRegistry registry = GenerationKernelRegistry.standard();
|
||||
try {
|
||||
return registry.requireSupported(registry.current()).implementationFingerprint();
|
||||
} catch (IOException failure) {
|
||||
throw new IllegalStateException("Cannot identify the noise cache implementation", failure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final class GeneratorCacheKey {
|
||||
private final IrisData data;
|
||||
private final Engine engine;
|
||||
|
||||
@@ -90,7 +90,8 @@ public class IrisNoiseGenerator {
|
||||
@Desc("The Noise Style")
|
||||
private IrisGeneratorStyle style = NoiseStyle.IRIS.style();
|
||||
@MinNumber(1)
|
||||
@Desc("Multiple octaves for multple generators of changing zooms added together")
|
||||
@MaxNumber(16)
|
||||
@Desc("Multiplies the style's octave count, capped at 16. Adds finer detail while preserving the base feature scale.")
|
||||
private int octaves = 1;
|
||||
@ArrayType(min = 1, type = IrisNoiseGenerator.class)
|
||||
@Desc("Apply a child noise generator to fracture the input coordinates of this generator")
|
||||
@@ -111,7 +112,7 @@ public class IrisNoiseGenerator {
|
||||
|
||||
GeneratorKey key = new GeneratorKey(data, engine, generatorSeed);
|
||||
CNG generator = generators.computeIfAbsent(key,
|
||||
ignored -> style.createNoCache(new RNG(generatorSeed), data).oct(octaves));
|
||||
ignored -> style.createForLayer(new RNG(generatorSeed), data, octaves));
|
||||
if (generator != null) {
|
||||
recentGenerator.set(new CachedGenerator(key, generator));
|
||||
}
|
||||
@@ -146,7 +147,7 @@ public class IrisNoiseGenerator {
|
||||
double n = cng.noiseFast2D(sampleX, sampleZ) * opacity;
|
||||
n = negative ? (-n + opacity) : n;
|
||||
n = (exponent != 1 ? n < 0 ? -Math.pow(-n, exponent) : Math.pow(n, exponent) : n) + offsetY;
|
||||
n = parametric ? IrisInterpolation.parametric(n, 1) : n;
|
||||
n = parametric ? IrisInterpolation.parametric(n, 2D) : n;
|
||||
n = bezier ? IrisInterpolation.bezier(n) : n;
|
||||
n = sinCentered ? IrisInterpolation.sinCenter(n) : n;
|
||||
|
||||
|
||||
@@ -27,523 +27,529 @@ import art.arcane.iris.util.project.stream.ProceduralStream;
|
||||
@Desc("Styles of noise")
|
||||
public enum NoiseStyle {
|
||||
@Desc("White Noise is like static. Useful for block scattering but not terrain.")
|
||||
STATIC(rng -> new CNG(rng, NoiseType.WHITE, 1D, 1)),
|
||||
STATIC(rng -> new CNG(rng, NoiseType.WHITE, 1D, 1), NoiseType.WHITE),
|
||||
|
||||
@Desc("White Noise is like static. Useful for block scattering but not terrain.")
|
||||
STATIC_BILINEAR(rng -> new CNG(rng, NoiseType.WHITE_BILINEAR, 1D, 1)),
|
||||
STATIC_BILINEAR(rng -> new CNG(rng, NoiseType.WHITE_BILINEAR, 1D, 1), NoiseType.WHITE_BILINEAR),
|
||||
|
||||
@Desc("White Noise is like static. Useful for block scattering but not terrain.")
|
||||
STATIC_BICUBIC(rng -> new CNG(rng, NoiseType.WHITE_BICUBIC, 1D, 1)),
|
||||
STATIC_BICUBIC(rng -> new CNG(rng, NoiseType.WHITE_BICUBIC, 1D, 1), NoiseType.WHITE_BICUBIC),
|
||||
|
||||
@Desc("White Noise is like static. Useful for block scattering but not terrain.")
|
||||
STATIC_HERMITE(rng -> new CNG(rng, NoiseType.WHITE_HERMITE, 1D, 1)),
|
||||
STATIC_HERMITE(rng -> new CNG(rng, NoiseType.WHITE_HERMITE, 1D, 1), NoiseType.WHITE_HERMITE),
|
||||
|
||||
@Desc("Wispy Perlin-looking simplex noise. The 'iris' style noise.")
|
||||
IRIS(rng -> CNG.signature(rng).scale(1)),
|
||||
IRIS(rng -> CNG.signature(rng)),
|
||||
|
||||
@Desc("Clover Noise")
|
||||
CLOVER(rng -> new CNG(rng, NoiseType.CLOVER, 1D, 1).scale(0.06).bake()),
|
||||
CLOVER(rng -> new CNG(rng, NoiseType.CLOVER, 1D, 1).bake(), NoiseType.CLOVER),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_STARCAST_3(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_3, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_STARCAST_3(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_3, 1D, 1), NoiseType.CLOVER_STARCAST_3),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_STARCAST_6(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_6, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_STARCAST_6(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_6, 1D, 1), NoiseType.CLOVER_STARCAST_6),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_STARCAST_9(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_9, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_STARCAST_9(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_9, 1D, 1), NoiseType.CLOVER_STARCAST_9),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_STARCAST_12(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_12, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_STARCAST_12(rng -> new CNG(rng, NoiseType.CLOVER_STARCAST_12, 1D, 1), NoiseType.CLOVER_STARCAST_12),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_BILINEAR_STARCAST_3(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR_STARCAST_3, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_BILINEAR_STARCAST_3(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR_STARCAST_3, 1D, 1), NoiseType.CLOVER_BILINEAR_STARCAST_3),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_BILINEAR_STARCAST_6(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR_STARCAST_6, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_BILINEAR_STARCAST_6(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR_STARCAST_6, 1D, 1), NoiseType.CLOVER_BILINEAR_STARCAST_6),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_BILINEAR_STARCAST_9(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR_STARCAST_9, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_BILINEAR_STARCAST_9(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR_STARCAST_9, 1D, 1), NoiseType.CLOVER_BILINEAR_STARCAST_9),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_BILINEAR_STARCAST_12(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR_STARCAST_12, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_BILINEAR_STARCAST_12(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR_STARCAST_12, 1D, 1), NoiseType.CLOVER_BILINEAR_STARCAST_12),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_HERMITE_STARCAST_3(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE_STARCAST_3, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_HERMITE_STARCAST_3(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE_STARCAST_3, 1D, 1), NoiseType.CLOVER_HERMITE_STARCAST_3),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_HERMITE_STARCAST_6(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE_STARCAST_6, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_HERMITE_STARCAST_6(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE_STARCAST_6, 1D, 1), NoiseType.CLOVER_HERMITE_STARCAST_6),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_HERMITE_STARCAST_9(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE_STARCAST_9, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_HERMITE_STARCAST_9(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE_STARCAST_9, 1D, 1), NoiseType.CLOVER_HERMITE_STARCAST_9),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_HERMITE_STARCAST_12(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE_STARCAST_12, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_HERMITE_STARCAST_12(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE_STARCAST_12, 1D, 1), NoiseType.CLOVER_HERMITE_STARCAST_12),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_BILINEAR(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_BILINEAR(rng -> new CNG(rng, NoiseType.CLOVER_BILINEAR, 1D, 1), NoiseType.CLOVER_BILINEAR),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_BICUBIC(rng -> new CNG(rng, NoiseType.CLOVER_BICUBIC, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_BICUBIC(rng -> new CNG(rng, NoiseType.CLOVER_BICUBIC, 1D, 1), NoiseType.CLOVER_BICUBIC),
|
||||
|
||||
@Desc("CLOVER noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CLOVER_HERMITE(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE, 1D, 1)),
|
||||
@Desc("Clover noise smoothed with the selected interpolation kernel.")
|
||||
CLOVER_HERMITE(rng -> new CNG(rng, NoiseType.CLOVER_HERMITE, 1D, 1), NoiseType.CLOVER_HERMITE),
|
||||
|
||||
@Desc("Vascular noise gets higher as the position nears a cell border.")
|
||||
VASCULAR(rng -> new CNG(rng, NoiseType.VASCULAR, 1D, 1)),
|
||||
VASCULAR(rng -> new CNG(rng, NoiseType.VASCULAR, 1D, 1), NoiseType.VASCULAR),
|
||||
|
||||
@Desc("It always returns 0.5")
|
||||
FLAT(rng -> new CNG(rng, NoiseType.FLAT, 1D, 1)),
|
||||
@Desc("It always returns 1.0")
|
||||
FLAT(rng -> new CNG(rng, NoiseType.FLAT, 1D, 1), NoiseType.FLAT),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR(rng -> new CNG(rng, NoiseType.CELLULAR, 1D, 1)),
|
||||
CELLULAR(rng -> new CNG(rng, NoiseType.CELLULAR, 1D, 1), NoiseType.CELLULAR),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_STARCAST_3(rng -> new CNG(rng, NoiseType.CELLULAR_STARCAST_3, 1D, 1)),
|
||||
CELLULAR_STARCAST_3(rng -> new CNG(rng, NoiseType.CELLULAR_STARCAST_3, 1D, 1), NoiseType.CELLULAR_STARCAST_3),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_STARCAST_6(rng -> new CNG(rng, NoiseType.CELLULAR_STARCAST_6, 1D, 1)),
|
||||
CELLULAR_STARCAST_6(rng -> new CNG(rng, NoiseType.CELLULAR_STARCAST_6, 1D, 1), NoiseType.CELLULAR_STARCAST_6),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_STARCAST_9(rng -> new CNG(rng, NoiseType.CELLULAR_STARCAST_9, 1D, 1)),
|
||||
CELLULAR_STARCAST_9(rng -> new CNG(rng, NoiseType.CELLULAR_STARCAST_9, 1D, 1), NoiseType.CELLULAR_STARCAST_9),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_STARCAST_12(rng -> new CNG(rng, NoiseType.CELLULAR_STARCAST_12, 1D, 1)),
|
||||
CELLULAR_STARCAST_12(rng -> new CNG(rng, NoiseType.CELLULAR_STARCAST_12, 1D, 1), NoiseType.CELLULAR_STARCAST_12),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_BILINEAR_STARCAST_3(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR_STARCAST_3, 1D, 1)),
|
||||
CELLULAR_BILINEAR_STARCAST_3(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR_STARCAST_3, 1D, 1), NoiseType.CELLULAR_BILINEAR_STARCAST_3),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_BILINEAR_STARCAST_6(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR_STARCAST_6, 1D, 1)),
|
||||
CELLULAR_BILINEAR_STARCAST_6(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR_STARCAST_6, 1D, 1), NoiseType.CELLULAR_BILINEAR_STARCAST_6),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_BILINEAR_STARCAST_9(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR_STARCAST_9, 1D, 1)),
|
||||
CELLULAR_BILINEAR_STARCAST_9(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR_STARCAST_9, 1D, 1), NoiseType.CELLULAR_BILINEAR_STARCAST_9),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_BILINEAR_STARCAST_12(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR_STARCAST_12, 1D, 1)),
|
||||
CELLULAR_BILINEAR_STARCAST_12(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR_STARCAST_12, 1D, 1), NoiseType.CELLULAR_BILINEAR_STARCAST_12),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_HERMITE_STARCAST_3(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE_STARCAST_3, 1D, 1)),
|
||||
CELLULAR_HERMITE_STARCAST_3(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE_STARCAST_3, 1D, 1), NoiseType.CELLULAR_HERMITE_STARCAST_3),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_HERMITE_STARCAST_6(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE_STARCAST_6, 1D, 1)),
|
||||
CELLULAR_HERMITE_STARCAST_6(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE_STARCAST_6, 1D, 1), NoiseType.CELLULAR_HERMITE_STARCAST_6),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_HERMITE_STARCAST_9(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE_STARCAST_9, 1D, 1)),
|
||||
CELLULAR_HERMITE_STARCAST_9(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE_STARCAST_9, 1D, 1), NoiseType.CELLULAR_HERMITE_STARCAST_9),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_HERMITE_STARCAST_12(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE_STARCAST_12, 1D, 1)),
|
||||
CELLULAR_HERMITE_STARCAST_12(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE_STARCAST_12, 1D, 1), NoiseType.CELLULAR_HERMITE_STARCAST_12),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_BILINEAR(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR, 1D, 1)),
|
||||
CELLULAR_BILINEAR(rng -> new CNG(rng, NoiseType.CELLULAR_BILINEAR, 1D, 1), NoiseType.CELLULAR_BILINEAR),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_BICUBIC(rng -> new CNG(rng, NoiseType.CELLULAR_BICUBIC, 1D, 1)),
|
||||
CELLULAR_BICUBIC(rng -> new CNG(rng, NoiseType.CELLULAR_BICUBIC, 1D, 1), NoiseType.CELLULAR_BICUBIC),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders.")
|
||||
CELLULAR_HERMITE(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE, 1D, 1)),
|
||||
CELLULAR_HERMITE(rng -> new CNG(rng, NoiseType.CELLULAR_HERMITE, 1D, 1), NoiseType.CELLULAR_HERMITE),
|
||||
|
||||
@Desc("Hexagonal cells with stable per-cell values.")
|
||||
HEXAGON(rng -> new CNG(rng, NoiseType.HEXAGON, 1D, 1).scale(1)),
|
||||
@Desc("Solid regular hexagons colored by a coherent simplex field.")
|
||||
HEXAGON(rng -> new CNG(rng, NoiseType.HEXAGON, 1D, 1), NoiseType.HEXAGON),
|
||||
|
||||
@Desc("Hex James substitution pattern with 3 large and 3 small recursive hex children plus gaps.")
|
||||
HEX_JAMES(rng -> new CNG(rng, NoiseType.HEX_JAMES, 1D, 1).scale(1)),
|
||||
@Desc("Recursive contained hexagons with alternating subdivision probabilities and simplex colors.")
|
||||
HEX_JAMES(rng -> new CNG(rng, NoiseType.HEX_JAMES, 1D, 1), NoiseType.HEX_JAMES),
|
||||
|
||||
@Desc("Interlocked solid hex cells with per-cell values from a smooth simplex heatmap.")
|
||||
HEX_SIMPLEX(rng -> new CNG(rng, NoiseType.HEX_SIMPLEX, 1D, 1).scale(1)),
|
||||
HEX_SIMPLEX(rng -> new CNG(rng, NoiseType.HEX_SIMPLEX, 1D, 1), NoiseType.HEX_SIMPLEX),
|
||||
|
||||
@Desc("Randomized finite-depth Sierpinski-style hex recursion with per-level random 3-large/3-small James substitution.")
|
||||
HEX_RANDOM_SIZE(rng -> new CNG(rng, NoiseType.HEX_RANDOM_SIZE, 1D, 1).scale(1)),
|
||||
@Desc("Finite-depth hexagonal subdivision selected by a seeded field, with coherent simplex colors.")
|
||||
HEX_RANDOM_SIZE(rng -> new CNG(rng, NoiseType.HEX_RANDOM_SIZE, 1D, 1), NoiseType.HEX_RANDOM_SIZE),
|
||||
|
||||
@Desc("Sierpinski triangle mask blended with simplex heat.")
|
||||
SIERPINSKI_TRIANGLE(rng -> new CNG(rng, NoiseType.SIERPINSKI_TRIANGLE, 1D, 1).scale(1)),
|
||||
@Desc("Finite-depth equilateral Sierpinski triangles colored by simplex heat.")
|
||||
SIERPINSKI_TRIANGLE(rng -> new CNG(rng, NoiseType.SIERPINSKI_TRIANGLE, 1D, 1), NoiseType.SIERPINSKI_TRIANGLE),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE(rng -> CNG.signaturePerlin(rng).scale(0.776).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE(rng -> CNG.signaturePerlin(rng).bake()),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_CELLULAR(rng -> CNG.signaturePerlin(rng, NoiseType.CELLULAR).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_CELLULAR(rng -> CNG.signaturePerlin(rng, NoiseType.CELLULAR).bake(), NoiseType.CELLULAR),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_CLOVER(rng -> CNG.signaturePerlin(rng, NoiseType.CLOVER).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_CLOVER(rng -> CNG.signaturePerlin(rng, NoiseType.CLOVER).bake(), NoiseType.CLOVER),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_HEXAGON(rng -> CNG.signaturePerlin(rng, NoiseType.HEXAGON).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_HEXAGON(rng -> CNG.signaturePerlin(rng, NoiseType.HEXAGON).bake(), NoiseType.HEXAGON),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_HEX_JAMES(rng -> CNG.signaturePerlin(rng, NoiseType.HEX_JAMES).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_HEX_JAMES(rng -> CNG.signaturePerlin(rng, NoiseType.HEX_JAMES).bake(), NoiseType.HEX_JAMES),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_HEX_SIMPLEX(rng -> CNG.signaturePerlin(rng, NoiseType.HEX_SIMPLEX).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_HEX_SIMPLEX(rng -> CNG.signaturePerlin(rng, NoiseType.HEX_SIMPLEX).bake(), NoiseType.HEX_SIMPLEX),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_HEX_RANDOM_SIZE(rng -> CNG.signaturePerlin(rng, NoiseType.HEX_RANDOM_SIZE).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_HEX_RANDOM_SIZE(rng -> CNG.signaturePerlin(rng, NoiseType.HEX_RANDOM_SIZE).bake(), NoiseType.HEX_RANDOM_SIZE),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_SIERPINSKI_TRIANGLE(rng -> CNG.signaturePerlin(rng, NoiseType.SIERPINSKI_TRIANGLE).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_SIERPINSKI_TRIANGLE(rng -> CNG.signaturePerlin(rng, NoiseType.SIERPINSKI_TRIANGLE).bake(), NoiseType.SIERPINSKI_TRIANGLE),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_SIMPLEX(rng -> CNG.signaturePerlin(rng, NoiseType.SIMPLEX).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_SIMPLEX(rng -> CNG.signaturePerlin(rng, NoiseType.SIMPLEX).bake(), NoiseType.SIMPLEX),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_GLOB(rng -> CNG.signaturePerlin(rng, NoiseType.GLOB).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_GLOB(rng -> CNG.signaturePerlin(rng, NoiseType.GLOB).bake(), NoiseType.GLOB),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_VASCULAR(rng -> CNG.signaturePerlin(rng, NoiseType.VASCULAR).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_VASCULAR(rng -> CNG.signaturePerlin(rng, NoiseType.VASCULAR).bake(), NoiseType.VASCULAR),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_CUBIC(rng -> CNG.signaturePerlin(rng, NoiseType.CUBIC).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_CUBIC(rng -> CNG.signaturePerlin(rng, NoiseType.CUBIC).bake(), NoiseType.CUBIC),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_SUPERFRACTAL(rng -> CNG.signaturePerlin(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_SUPERFRACTAL(rng -> CNG.signaturePerlin(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX).bake(), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Classic German Engineering")
|
||||
NOWHERE_FRACTAL(rng -> CNG.signaturePerlin(rng, NoiseType.FRACTAL_BILLOW_PERLIN).scale(1).bake()),
|
||||
@Desc("Perlin-warped noise with broad, flowing distortion.")
|
||||
NOWHERE_FRACTAL(rng -> CNG.signaturePerlin(rng, NoiseType.FRACTAL_BILLOW_PERLIN).bake(), NoiseType.FRACTAL_BILLOW_PERLIN),
|
||||
|
||||
@Desc("Wispy Perlin-looking simplex noise. The 'iris' style noise.")
|
||||
IRIS_DOUBLE(rng -> CNG.signatureDouble(rng).scale(1)),
|
||||
IRIS_DOUBLE(rng -> CNG.signatureDouble(rng)),
|
||||
|
||||
@Desc("Wispy Perlin-looking simplex noise. The 'iris' style noise.")
|
||||
IRIS_THICK(rng -> CNG.signatureThick(rng).scale(1)),
|
||||
IRIS_THICK(rng -> CNG.signatureThick(rng)),
|
||||
|
||||
@Desc("Wispy Perlin-looking simplex noise. The 'iris' style noise.")
|
||||
IRIS_HALF(rng -> CNG.signatureHalf(rng).scale(1)),
|
||||
IRIS_HALF(rng -> CNG.signatureHalf(rng)),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise.")
|
||||
SIMPLEX(rng -> new CNG(rng, 1D, 1).scale(1)),
|
||||
SIMPLEX(rng -> new CNG(rng, 1D, 1)),
|
||||
|
||||
@Desc("Very Detailed smoke using simplex fractured with fractal billow simplex at high octaves.")
|
||||
FRACTAL_SMOKE(rng -> new CNG(rng, 1D, 1).fractureWith(new CNG(rng.nextParallelRNG(1), NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 8).scale(0.2), 1000).scale(0.34)),
|
||||
FRACTAL_SMOKE(rng -> new CNG(rng, 1D, 1).fractureWith(new CNG(rng.nextParallelRNG(1), NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 8).scale(0.2), 1000), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("Thinner Veins.")
|
||||
VASCULAR_THIN(rng -> new CNG(rng.nextParallelRNG(1), NoiseType.VASCULAR, 1D, 1).scale(1).pow(0.65)),
|
||||
VASCULAR_THIN(rng -> new CNG(rng.nextParallelRNG(1), NoiseType.VASCULAR, 1D, 1).scale(1).pow(1D / 0.65D), NoiseType.VASCULAR),
|
||||
|
||||
@Desc("Cells of simplex noise")
|
||||
SIMPLEX_CELLS(rng -> new CNG(rng.nextParallelRNG(1), NoiseType.SIMPLEX, 1D, 1).scale(1).fractureWith(new CNG(rng.nextParallelRNG(8), NoiseType.CELLULAR, 1D, 1).scale(1), 200)),
|
||||
SIMPLEX_CELLS(rng -> new CNG(rng.nextParallelRNG(1), NoiseType.SIMPLEX, 1D, 1).scale(1).fractureWith(new CNG(rng.nextParallelRNG(8), NoiseType.CELLULAR, 1D, 1).scale(1), 200), NoiseType.SIMPLEX),
|
||||
|
||||
@Desc("Veins of simplex noise")
|
||||
SIMPLEX_VASCULAR(rng -> new CNG(rng.nextParallelRNG(1), NoiseType.SIMPLEX, 1D, 1).scale(1).fractureWith(new CNG(rng.nextParallelRNG(8), NoiseType.VASCULAR, 1D, 1).scale(1), 200)),
|
||||
SIMPLEX_VASCULAR(rng -> new CNG(rng.nextParallelRNG(1), NoiseType.SIMPLEX, 1D, 1).scale(1).fractureWith(new CNG(rng.nextParallelRNG(8), NoiseType.VASCULAR, 1D, 1).scale(1), 200), NoiseType.SIMPLEX),
|
||||
|
||||
@Desc("Very Detailed fluid using simplex fractured with fractal billow simplex at high octaves.")
|
||||
FRACTAL_WATER(rng -> new CNG(rng, 1D, 1).fractureWith(new CNG(rng.nextParallelRNG(1), NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 9).scale(0.03), 9900).scale(1.14)),
|
||||
FRACTAL_WATER(rng -> new CNG(rng, 1D, 1).fractureWith(new CNG(rng.nextParallelRNG(1), NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 9).scale(0.03), 9900), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Perlin. Like simplex but more natural")
|
||||
PERLIN(rng -> new CNG(rng, NoiseType.PERLIN, 1D, 1).scale(1.15)),
|
||||
PERLIN(rng -> new CNG(rng, NoiseType.PERLIN, 1D, 1), NoiseType.PERLIN),
|
||||
|
||||
@Desc("Perlin. Like simplex but more natural")
|
||||
PERLIN_IRIS(rng -> CNG.signature(rng, NoiseType.PERLIN).scale(1.47)),
|
||||
PERLIN_IRIS(rng -> CNG.signature(rng, NoiseType.PERLIN), NoiseType.PERLIN),
|
||||
|
||||
@Desc("Perlin. Like simplex but more natural")
|
||||
PERLIN_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.PERLIN).scale(1.47)),
|
||||
PERLIN_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.PERLIN), NoiseType.PERLIN),
|
||||
|
||||
@Desc("Perlin. Like simplex but more natural")
|
||||
PERLIN_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.PERLIN).scale(1.47)),
|
||||
PERLIN_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.PERLIN), NoiseType.PERLIN),
|
||||
|
||||
@Desc("Perlin. Like simplex but more natural")
|
||||
PERLIN_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.PERLIN).scale(1.47)),
|
||||
PERLIN_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.PERLIN), NoiseType.PERLIN),
|
||||
|
||||
@Desc("Billow Fractal Perlin Noise.")
|
||||
FRACTAL_BILLOW_PERLIN(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_PERLIN, 1D, 1).scale(1.47)),
|
||||
FRACTAL_BILLOW_PERLIN(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_PERLIN, 1D, 1), NoiseType.FRACTAL_BILLOW_PERLIN),
|
||||
|
||||
@Desc("Billow Fractal Perlin Noise. 2 Octaves")
|
||||
BIOCTAVE_FRACTAL_BILLOW_PERLIN(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_PERLIN, 1D, 2).scale(1.17)),
|
||||
BIOCTAVE_FRACTAL_BILLOW_PERLIN(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_PERLIN, 1D, 2), NoiseType.FRACTAL_BILLOW_PERLIN),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. Single octave.")
|
||||
FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 1)),
|
||||
FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 1), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. Single octave.")
|
||||
FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 1)),
|
||||
FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 1), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Iris Noise. Single octave.")
|
||||
FRACTAL_BILLOW_IRIS(rng -> CNG.signature(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX)),
|
||||
FRACTAL_BILLOW_IRIS(rng -> CNG.signature(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Iris Noise. Single octave.")
|
||||
FRACTAL_FBM_IRIS(rng -> CNG.signature(rng, NoiseType.FRACTAL_FBM_SIMPLEX)),
|
||||
FRACTAL_FBM_IRIS(rng -> CNG.signature(rng, NoiseType.FRACTAL_FBM_SIMPLEX), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Iris Noise. Single octave.")
|
||||
FRACTAL_BILLOW_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX)),
|
||||
FRACTAL_BILLOW_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Iris Noise. Single octave.")
|
||||
FRACTAL_FBM_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.FRACTAL_FBM_SIMPLEX)),
|
||||
FRACTAL_FBM_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.FRACTAL_FBM_SIMPLEX), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Iris Noise. Single octave.")
|
||||
FRACTAL_BILLOW_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX)),
|
||||
FRACTAL_BILLOW_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Iris Noise. Single octave.")
|
||||
FRACTAL_FBM_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.FRACTAL_FBM_SIMPLEX)),
|
||||
FRACTAL_FBM_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.FRACTAL_FBM_SIMPLEX), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Fractal hexagonal cell noise.")
|
||||
FRACTAL_HEXAGON(rng -> new CNG(rng, NoiseType.HEXAGON, 1D, 4).scale(1)),
|
||||
FRACTAL_HEXAGON(rng -> new CNG(rng, NoiseType.HEXAGON, 1D, 4), NoiseType.HEXAGON),
|
||||
|
||||
@Desc("Fractal Hex James substitution pattern with recursive 3-large/3-small child hexes and gaps.")
|
||||
FRACTAL_HEX_JAMES(rng -> new CNG(rng, NoiseType.HEX_JAMES, 1D, 4).scale(1)),
|
||||
@Desc("Recursive contained hexagons colored by fractal simplex noise.")
|
||||
FRACTAL_HEX_JAMES(rng -> new CNG(rng, NoiseType.HEX_JAMES, 1D, 4), NoiseType.HEX_JAMES),
|
||||
|
||||
@Desc("Interlocked solid hex cells with per-cell fractal simplex heatmap values.")
|
||||
FRACTAL_HEX_SIMPLEX(rng -> new CNG(rng, NoiseType.HEX_SIMPLEX, 1D, 4).scale(1)),
|
||||
FRACTAL_HEX_SIMPLEX(rng -> new CNG(rng, NoiseType.HEX_SIMPLEX, 1D, 4), NoiseType.HEX_SIMPLEX),
|
||||
|
||||
@Desc("Fractal hexagonal gradient noise with randomized local hex sizes and blended random/simplex heatmaps.")
|
||||
FRACTAL_HEX_RANDOM_SIZE(rng -> new CNG(rng, NoiseType.HEX_RANDOM_SIZE, 1D, 4).scale(1)),
|
||||
@Desc("Recursive hexagonal subdivision colored by fractal simplex noise.")
|
||||
FRACTAL_HEX_RANDOM_SIZE(rng -> new CNG(rng, NoiseType.HEX_RANDOM_SIZE, 1D, 4), NoiseType.HEX_RANDOM_SIZE),
|
||||
|
||||
@Desc("Fractal Sierpinski triangle mask blended with simplex heat.")
|
||||
FRACTAL_SIERPINSKI_TRIANGLE(rng -> new CNG(rng, NoiseType.SIERPINSKI_TRIANGLE, 1D, 4).scale(1)),
|
||||
@Desc("Finite-depth equilateral Sierpinski triangles colored by fractal simplex heat.")
|
||||
FRACTAL_SIERPINSKI_TRIANGLE(rng -> new CNG(rng, NoiseType.SIERPINSKI_TRIANGLE, 1D, 4), NoiseType.SIERPINSKI_TRIANGLE),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. Single octave.")
|
||||
FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 1)),
|
||||
FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 1), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. 2 octaves.")
|
||||
BIOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 2)),
|
||||
BIOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 2), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. 2 octaves.")
|
||||
BIOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 2)),
|
||||
BIOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 2), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. 2 octaves.")
|
||||
BIOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 2)),
|
||||
BIOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 2), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. 3 octaves.")
|
||||
TRIOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 3)),
|
||||
TRIOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 3), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. 3 octaves.")
|
||||
TRIOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 3)),
|
||||
TRIOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 3), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. 3 octaves.")
|
||||
TRIOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 3)),
|
||||
TRIOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 3), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. 4 octaves.")
|
||||
QUADOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 4)),
|
||||
QUADOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 4), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. 4 octaves.")
|
||||
QUADOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 4)),
|
||||
QUADOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 4), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. 4 octaves.")
|
||||
QUADOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 4)),
|
||||
QUADOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 4), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. 5 octaves.")
|
||||
QUINTOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 5)),
|
||||
QUINTOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 5), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. 5 octaves.")
|
||||
QUINTOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 5)),
|
||||
QUINTOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 5), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. 5 octaves.")
|
||||
QUINTOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 5)),
|
||||
QUINTOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 5), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. 6 octaves.")
|
||||
SEXOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 6)),
|
||||
SEXOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 6), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. 6 octaves.")
|
||||
SEXOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 6)),
|
||||
SEXOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 6), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. 6 octaves.")
|
||||
SEXOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 6)),
|
||||
SEXOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 6), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. 7 octaves.")
|
||||
SEPTOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 7)),
|
||||
SEPTOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 7), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. 7 octaves.")
|
||||
SEPTOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 7)),
|
||||
SEPTOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 7), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. 7 octaves.")
|
||||
SEPTOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 7)),
|
||||
SEPTOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 7), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. 8 octaves.")
|
||||
OCTOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 8)),
|
||||
OCTOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 8), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. 8 octaves.")
|
||||
OCTOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 8)),
|
||||
OCTOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 8), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. 8 octaves.")
|
||||
OCTOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 8)),
|
||||
OCTOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 8), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. 9 octaves.")
|
||||
NONOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 9)),
|
||||
NONOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 9), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. 9 octaves.")
|
||||
NONOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 9)),
|
||||
NONOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 9), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. 9 octaves.")
|
||||
NONOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 9)),
|
||||
NONOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 9), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Rigid Multi Fractal Simplex Noise. 10 octaves.")
|
||||
VIGOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 10)),
|
||||
VIGOCTAVE_FRACTAL_RM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX, 1D, 10), NoiseType.FRACTAL_RIGID_MULTI_SIMPLEX),
|
||||
|
||||
@Desc("Billow Fractal Simplex Noise. 10 octaves.")
|
||||
VIGOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 10)),
|
||||
VIGOCTAVE_FRACTAL_BILLOW_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_BILLOW_SIMPLEX, 1D, 10), NoiseType.FRACTAL_BILLOW_SIMPLEX),
|
||||
|
||||
@Desc("FBM Fractal Simplex Noise. 10 octaves.")
|
||||
VIGOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 10)),
|
||||
VIGOCTAVE_FRACTAL_FBM_SIMPLEX(rng -> new CNG(rng, NoiseType.FRACTAL_FBM_SIMPLEX, 1D, 10), NoiseType.FRACTAL_FBM_SIMPLEX),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise. Uses 2 octaves")
|
||||
BIOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 2).scale(1D / 2D)),
|
||||
BIOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 2)),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise. Uses 3 octaves")
|
||||
TRIOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 3).scale(1D / 3D)),
|
||||
TRIOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 3)),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise. Uses 4 octaves")
|
||||
QUADOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 4).scale(1D / 4D)),
|
||||
QUADOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 4)),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise. Uses 5 octaves")
|
||||
QUINTOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 5).scale(1D / 5D)),
|
||||
QUINTOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 5)),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise. Uses 6 octaves")
|
||||
SEXOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 6).scale(1D / 6D)),
|
||||
SEXOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 6)),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise. Uses 7 octaves")
|
||||
SEPTOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 7).scale(1D / 12D)),
|
||||
SEPTOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 7)),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise. Uses 8 octaves")
|
||||
OCTOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 8).scale(1D / 25D)),
|
||||
OCTOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 8)),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise. Uses 9 octaves")
|
||||
NONOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 9).scale(1D / 50D)),
|
||||
NONOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 9)),
|
||||
|
||||
@Desc("Basic, Smooth & Fast Simplex noise. Uses 10 octaves")
|
||||
VIGOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 10).scale(1D / 100D)),
|
||||
VIGOCTAVE_SIMPLEX(rng -> new CNG(rng, 1D, 10)),
|
||||
|
||||
@Desc("Glob noise is like cellular, but with globs...")
|
||||
GLOB(rng -> new CNG(rng, NoiseType.GLOB, 1D, 1)),
|
||||
GLOB(rng -> new CNG(rng, NoiseType.GLOB, 1D, 1), NoiseType.GLOB),
|
||||
|
||||
@Desc("Glob noise is like cellular, but with globs...")
|
||||
GLOB_IRIS(rng -> CNG.signature(rng, NoiseType.GLOB)),
|
||||
GLOB_IRIS(rng -> CNG.signature(rng, NoiseType.GLOB), NoiseType.GLOB),
|
||||
|
||||
@Desc("Glob noise is like cellular, but with globs...")
|
||||
GLOB_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.GLOB)),
|
||||
GLOB_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.GLOB), NoiseType.GLOB),
|
||||
|
||||
@Desc("Glob noise is like cellular, but with globs...")
|
||||
GLOB_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.GLOB)),
|
||||
GLOB_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.GLOB), NoiseType.GLOB),
|
||||
|
||||
@Desc("Glob noise is like cellular, but with globs...")
|
||||
GLOB_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.GLOB)),
|
||||
GLOB_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.GLOB), NoiseType.GLOB),
|
||||
|
||||
@Desc("Cubic Noise")
|
||||
CUBIC(rng -> new CNG(rng, NoiseType.CUBIC, 1D, 1).scale(256)),
|
||||
CUBIC(rng -> new CNG(rng, NoiseType.CUBIC, 1D, 1), NoiseType.CUBIC),
|
||||
|
||||
@Desc("Fractal Cubic Noise")
|
||||
FRACTAL_CUBIC(rng -> new CNG(rng, NoiseType.FRACTAL_CUBIC, 1D, 1).scale(2)),
|
||||
FRACTAL_CUBIC(rng -> new CNG(rng, NoiseType.FRACTAL_CUBIC, 1D, 1), NoiseType.FRACTAL_CUBIC),
|
||||
|
||||
@Desc("Fractal Cubic Noise With Iris Swirls")
|
||||
FRACTAL_CUBIC_IRIS(rng -> CNG.signature(rng, NoiseType.FRACTAL_CUBIC).scale(2)),
|
||||
FRACTAL_CUBIC_IRIS(rng -> CNG.signature(rng, NoiseType.FRACTAL_CUBIC), NoiseType.FRACTAL_CUBIC),
|
||||
|
||||
@Desc("Fractal Cubic Noise With Iris Swirls")
|
||||
FRACTAL_CUBIC_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.FRACTAL_CUBIC).scale(2)),
|
||||
FRACTAL_CUBIC_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.FRACTAL_CUBIC), NoiseType.FRACTAL_CUBIC),
|
||||
|
||||
@Desc("Fractal Cubic Noise With Iris Swirls")
|
||||
FRACTAL_CUBIC_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.FRACTAL_CUBIC).scale(2)),
|
||||
FRACTAL_CUBIC_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.FRACTAL_CUBIC), NoiseType.FRACTAL_CUBIC),
|
||||
|
||||
@Desc("Fractal Cubic Noise With Iris Swirls")
|
||||
FRACTAL_CUBIC_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.FRACTAL_CUBIC).scale(2)),
|
||||
FRACTAL_CUBIC_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.FRACTAL_CUBIC), NoiseType.FRACTAL_CUBIC),
|
||||
|
||||
@Desc("Fractal Cubic Noise, 2 Octaves")
|
||||
BIOCTAVE_FRACTAL_CUBIC(rng -> new CNG(rng, NoiseType.FRACTAL_CUBIC, 1D, 2).scale(2)),
|
||||
BIOCTAVE_FRACTAL_CUBIC(rng -> new CNG(rng, NoiseType.FRACTAL_CUBIC, 1D, 2), NoiseType.FRACTAL_CUBIC),
|
||||
|
||||
@Desc("Fractal Cubic Noise, 3 Octaves")
|
||||
TRIOCTAVE_FRACTAL_CUBIC(rng -> new CNG(rng, NoiseType.FRACTAL_CUBIC, 1D, 3).scale(1.5)),
|
||||
TRIOCTAVE_FRACTAL_CUBIC(rng -> new CNG(rng, NoiseType.FRACTAL_CUBIC, 1D, 3), NoiseType.FRACTAL_CUBIC),
|
||||
|
||||
@Desc("Fractal Cubic Noise, 4 Octaves")
|
||||
QUADOCTAVE_FRACTAL_CUBIC(rng -> new CNG(rng, NoiseType.FRACTAL_CUBIC, 1D, 4).scale(1)),
|
||||
QUADOCTAVE_FRACTAL_CUBIC(rng -> new CNG(rng, NoiseType.FRACTAL_CUBIC, 1D, 4), NoiseType.FRACTAL_CUBIC),
|
||||
|
||||
@Desc("Cubic Noise")
|
||||
CUBIC_IRIS(rng -> CNG.signature(rng, NoiseType.CUBIC).scale(256)),
|
||||
CUBIC_IRIS(rng -> CNG.signature(rng, NoiseType.CUBIC), NoiseType.CUBIC),
|
||||
|
||||
@Desc("Cubic Noise")
|
||||
CUBIC_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.CUBIC).scale(256)),
|
||||
CUBIC_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.CUBIC), NoiseType.CUBIC),
|
||||
|
||||
@Desc("Cubic Noise")
|
||||
CUBIC_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.CUBIC).scale(256)),
|
||||
CUBIC_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.CUBIC), NoiseType.CUBIC),
|
||||
|
||||
@Desc("Cubic Noise")
|
||||
CUBIC_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.CUBIC).scale(256)),
|
||||
CUBIC_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.CUBIC), NoiseType.CUBIC),
|
||||
|
||||
@Desc("Hexagonal cell noise distorted using Iris styled wispy noise.")
|
||||
HEXAGON_IRIS(rng -> CNG.signature(rng, NoiseType.HEXAGON).scale(1)),
|
||||
HEXAGON_IRIS(rng -> CNG.signature(rng, NoiseType.HEXAGON), NoiseType.HEXAGON),
|
||||
|
||||
@Desc("Hexagonal cell noise distorted using Iris styled wispy noise.")
|
||||
HEXAGON_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.HEXAGON).scale(1)),
|
||||
HEXAGON_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.HEXAGON), NoiseType.HEXAGON),
|
||||
|
||||
@Desc("Hexagonal cell noise distorted using Iris styled wispy noise.")
|
||||
HEXAGON_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.HEXAGON).scale(1)),
|
||||
HEXAGON_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.HEXAGON), NoiseType.HEXAGON),
|
||||
|
||||
@Desc("Hexagonal cell noise distorted using Iris styled wispy noise.")
|
||||
HEXAGON_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.HEXAGON).scale(1)),
|
||||
HEXAGON_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.HEXAGON), NoiseType.HEXAGON),
|
||||
|
||||
@Desc("Hex James substitution pattern distorted using Iris styled wispy noise.")
|
||||
HEX_JAMES_IRIS(rng -> CNG.signature(rng, NoiseType.HEX_JAMES).scale(1)),
|
||||
HEX_JAMES_IRIS(rng -> CNG.signature(rng, NoiseType.HEX_JAMES), NoiseType.HEX_JAMES),
|
||||
|
||||
@Desc("Hex James substitution pattern distorted using Iris styled wispy noise.")
|
||||
HEX_JAMES_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.HEX_JAMES).scale(1)),
|
||||
HEX_JAMES_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.HEX_JAMES), NoiseType.HEX_JAMES),
|
||||
|
||||
@Desc("Hex James substitution pattern distorted using Iris styled wispy noise.")
|
||||
HEX_JAMES_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.HEX_JAMES).scale(1)),
|
||||
HEX_JAMES_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.HEX_JAMES), NoiseType.HEX_JAMES),
|
||||
|
||||
@Desc("Hex James substitution pattern distorted using Iris styled wispy noise.")
|
||||
HEX_JAMES_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.HEX_JAMES).scale(1)),
|
||||
HEX_JAMES_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.HEX_JAMES), NoiseType.HEX_JAMES),
|
||||
|
||||
@Desc("Interlocked solid hex-cell simplex heatmap distorted using Iris styled wispy noise.")
|
||||
HEX_SIMPLEX_IRIS(rng -> CNG.signature(rng, NoiseType.HEX_SIMPLEX).scale(1)),
|
||||
HEX_SIMPLEX_IRIS(rng -> CNG.signature(rng, NoiseType.HEX_SIMPLEX), NoiseType.HEX_SIMPLEX),
|
||||
|
||||
@Desc("Interlocked solid hex-cell simplex heatmap distorted using Iris styled wispy noise.")
|
||||
HEX_SIMPLEX_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.HEX_SIMPLEX).scale(1)),
|
||||
HEX_SIMPLEX_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.HEX_SIMPLEX), NoiseType.HEX_SIMPLEX),
|
||||
|
||||
@Desc("Interlocked solid hex-cell simplex heatmap distorted using Iris styled wispy noise.")
|
||||
HEX_SIMPLEX_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.HEX_SIMPLEX).scale(1)),
|
||||
HEX_SIMPLEX_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.HEX_SIMPLEX), NoiseType.HEX_SIMPLEX),
|
||||
|
||||
@Desc("Interlocked solid hex-cell simplex heatmap distorted using Iris styled wispy noise.")
|
||||
HEX_SIMPLEX_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.HEX_SIMPLEX).scale(1)),
|
||||
HEX_SIMPLEX_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.HEX_SIMPLEX), NoiseType.HEX_SIMPLEX),
|
||||
|
||||
@Desc("Hexagonal random-size gradient noise and distorted using Iris styled wispy noise.")
|
||||
HEX_RANDOM_SIZE_IRIS(rng -> CNG.signature(rng, NoiseType.HEX_RANDOM_SIZE).scale(1)),
|
||||
HEX_RANDOM_SIZE_IRIS(rng -> CNG.signature(rng, NoiseType.HEX_RANDOM_SIZE), NoiseType.HEX_RANDOM_SIZE),
|
||||
|
||||
@Desc("Hexagonal random-size gradient noise and distorted using Iris styled wispy noise.")
|
||||
HEX_RANDOM_SIZE_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.HEX_RANDOM_SIZE).scale(1)),
|
||||
HEX_RANDOM_SIZE_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.HEX_RANDOM_SIZE), NoiseType.HEX_RANDOM_SIZE),
|
||||
|
||||
@Desc("Hexagonal random-size gradient noise and distorted using Iris styled wispy noise.")
|
||||
HEX_RANDOM_SIZE_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.HEX_RANDOM_SIZE).scale(1)),
|
||||
HEX_RANDOM_SIZE_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.HEX_RANDOM_SIZE), NoiseType.HEX_RANDOM_SIZE),
|
||||
|
||||
@Desc("Hexagonal random-size gradient noise and distorted using Iris styled wispy noise.")
|
||||
HEX_RANDOM_SIZE_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.HEX_RANDOM_SIZE).scale(1)),
|
||||
HEX_RANDOM_SIZE_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.HEX_RANDOM_SIZE), NoiseType.HEX_RANDOM_SIZE),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders. Cells are distorted using Iris styled wispy noise.")
|
||||
CELLULAR_IRIS(rng -> CNG.signature(rng, NoiseType.CELLULAR)),
|
||||
CELLULAR_IRIS(rng -> CNG.signature(rng, NoiseType.CELLULAR), NoiseType.CELLULAR),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders. Cells are distorted using Iris styled wispy noise.")
|
||||
CELLULAR_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.CELLULAR)),
|
||||
CELLULAR_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.CELLULAR), NoiseType.CELLULAR),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders. Cells are distorted using Iris styled wispy noise.")
|
||||
CELLULAR_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.CELLULAR)),
|
||||
CELLULAR_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.CELLULAR), NoiseType.CELLULAR),
|
||||
|
||||
@Desc("Cellular noise creates the same noise level for cells, changes noise level on cell borders. Cells are distorted using Iris styled wispy noise.")
|
||||
CELLULAR_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.CELLULAR)),
|
||||
CELLULAR_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.CELLULAR), NoiseType.CELLULAR),
|
||||
|
||||
@Desc("Inverse of vascular, height gets to 1.0 as it approaches the center of a cell")
|
||||
CELLULAR_HEIGHT(rng -> new CNG(rng, NoiseType.CELLULAR_HEIGHT, 1D, 1)),
|
||||
CELLULAR_HEIGHT(rng -> new CNG(rng, NoiseType.CELLULAR_HEIGHT, 1D, 1), NoiseType.CELLULAR_HEIGHT),
|
||||
|
||||
@Desc("Inverse of vascular, height gets to 1.0 as it approaches the center of a cell, using the iris style.")
|
||||
CELLULAR_HEIGHT_IRIS(rng -> CNG.signature(rng, NoiseType.CELLULAR_HEIGHT)),
|
||||
CELLULAR_HEIGHT_IRIS(rng -> CNG.signature(rng, NoiseType.CELLULAR_HEIGHT), NoiseType.CELLULAR_HEIGHT),
|
||||
|
||||
@Desc("Inverse of vascular, height gets to 1.0 as it approaches the center of a cell, using the iris style.")
|
||||
CELLULAR_HEIGHT_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.CELLULAR_HEIGHT)),
|
||||
CELLULAR_HEIGHT_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.CELLULAR_HEIGHT), NoiseType.CELLULAR_HEIGHT),
|
||||
|
||||
@Desc("Inverse of vascular, height gets to 1.0 as it approaches the center of a cell, using the iris style.")
|
||||
CELLULAR_HEIGHT_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.CELLULAR_HEIGHT)),
|
||||
CELLULAR_HEIGHT_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.CELLULAR_HEIGHT), NoiseType.CELLULAR_HEIGHT),
|
||||
|
||||
@Desc("Inverse of vascular, height gets to 1.0 as it approaches the center of a cell, using the iris style.")
|
||||
CELLULAR_HEIGHT_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.CELLULAR_HEIGHT)),
|
||||
CELLULAR_HEIGHT_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.CELLULAR_HEIGHT), NoiseType.CELLULAR_HEIGHT),
|
||||
|
||||
@Desc("Vascular noise gets higher as the position nears a cell border. Cells are distorted using Iris styled wispy noise.")
|
||||
VASCULAR_IRIS(rng -> CNG.signature(rng, NoiseType.VASCULAR)),
|
||||
VASCULAR_IRIS(rng -> CNG.signature(rng, NoiseType.VASCULAR), NoiseType.VASCULAR),
|
||||
|
||||
@Desc("Vascular noise gets higher as the position nears a cell border. Cells are distorted using Iris styled wispy noise.")
|
||||
VASCULAR_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.VASCULAR)),
|
||||
VASCULAR_IRIS_DOUBLE(rng -> CNG.signatureDouble(rng, NoiseType.VASCULAR), NoiseType.VASCULAR),
|
||||
|
||||
@Desc("Vascular noise gets higher as the position nears a cell border. Cells are distorted using Iris styled wispy noise.")
|
||||
VASCULAR_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.VASCULAR)),
|
||||
VASCULAR_IRIS_THICK(rng -> CNG.signatureThick(rng, NoiseType.VASCULAR), NoiseType.VASCULAR),
|
||||
|
||||
@Desc("Vascular noise gets higher as the position nears a cell border. Cells are distorted using Iris styled wispy noise.")
|
||||
VASCULAR_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.VASCULAR)),
|
||||
VASCULAR_IRIS_HALF(rng -> CNG.signatureHalf(rng, NoiseType.VASCULAR), NoiseType.VASCULAR),
|
||||
;
|
||||
|
||||
private final CNGFactory f;
|
||||
private final NoiseType type;
|
||||
|
||||
NoiseStyle(CNGFactory f) {
|
||||
this(f, NoiseType.SIMPLEX);
|
||||
}
|
||||
|
||||
NoiseStyle(CNGFactory f, NoiseType type) {
|
||||
this.f = f;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ProceduralStream<Double> stream(RNG seed) {
|
||||
@@ -555,7 +561,7 @@ public enum NoiseStyle {
|
||||
}
|
||||
|
||||
public CNG create(RNG seed) {
|
||||
CNG cng = f.create(seed).bake();
|
||||
CNG cng = f.create(seed).bake().scale(type.getCoordinateScale()).bake();
|
||||
cng.setLeakStyle(this);
|
||||
return cng;
|
||||
}
|
||||
|
||||
+147
-117
@@ -19,13 +19,13 @@
|
||||
package art.arcane.iris.util.project.interpolation;
|
||||
|
||||
import com.google.common.util.concurrent.AtomicDouble;
|
||||
import art.arcane.volmlib.util.interpolation.Starcast;
|
||||
import art.arcane.iris.engine.object.NoiseStyle;
|
||||
import art.arcane.volmlib.util.function.NoiseProvider;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
import art.arcane.iris.util.project.noise.CNG;
|
||||
|
||||
public class IrisInterpolation {
|
||||
private static final double[][] STARCAST_OFFSETS = createStarcastOffsets();
|
||||
public static CNG cng = NoiseStyle.SIMPLEX.create(new RNG());
|
||||
private static final ThreadLocal<NoiseSampleCache2D> NOISE_SAMPLE_CACHE_2D = ThreadLocal.withInitial(() -> new NoiseSampleCache2D(64));
|
||||
private static final ThreadLocal<NoiseBoundsSampleCache2D> NOISE_BOUNDS_SAMPLE_CACHE_2D = ThreadLocal.withInitial(() -> new NoiseBoundsSampleCache2D(64));
|
||||
@@ -35,8 +35,8 @@ public class IrisInterpolation {
|
||||
}
|
||||
|
||||
public static double parametric(double t, double alpha) {
|
||||
double sqt = Math.pow(t, alpha);
|
||||
return sqt / (alpha * (sqt - Math.pow(t, alpha - 1)) + 1.0d);
|
||||
double forward = Math.pow(t, alpha);
|
||||
return forward / (forward + Math.pow(1D - t, alpha));
|
||||
}
|
||||
|
||||
public static float lerpf(float a, float b, float f) {
|
||||
@@ -287,13 +287,17 @@ public class IrisInterpolation {
|
||||
return (int) Math.floor(coord / radius);
|
||||
}
|
||||
|
||||
public static double getBilinearNoise(int x, int z, double rad, NoiseProvider n) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
public static int getRadiusFactor(double coord, double radius) {
|
||||
return (int) Math.floor(coord / radius);
|
||||
}
|
||||
|
||||
public static double getBilinearNoise(double x, double z, double rad, NoiseProvider n) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
@@ -307,13 +311,13 @@ public class IrisInterpolation {
|
||||
//@done
|
||||
}
|
||||
|
||||
public static double getBilinearBezierNoise(int x, int z, double rad, NoiseProvider n) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
public static double getBilinearBezierNoise(double x, double z, double rad, NoiseProvider n) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
//@builder
|
||||
@@ -326,13 +330,13 @@ public class IrisInterpolation {
|
||||
//@done
|
||||
}
|
||||
|
||||
public static double getBilinearParametricNoise(int x, int z, double rad, NoiseProvider n, double a) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
public static double getBilinearParametricNoise(double x, double z, double rad, NoiseProvider n, double a) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
//@builder
|
||||
@@ -345,13 +349,13 @@ public class IrisInterpolation {
|
||||
//@done
|
||||
}
|
||||
|
||||
public static double getBilinearCenterSineNoise(int x, int z, double rad, NoiseProvider n) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
public static double getBilinearCenterSineNoise(double x, double z, double rad, NoiseProvider n) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
//@builder
|
||||
@@ -364,17 +368,17 @@ public class IrisInterpolation {
|
||||
//@done
|
||||
}
|
||||
|
||||
public static double getBicubicNoise(int x, int z, double rad, NoiseProvider n) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x0 = (int) Math.round((fx - 1) * rad);
|
||||
int z0 = (int) Math.round((fz - 1) * rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
int x3 = (int) Math.round((fx + 2) * rad);
|
||||
int z3 = (int) Math.round((fz + 2) * rad);
|
||||
public static double getBicubicNoise(double x, double z, double rad, NoiseProvider n) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x0 = (fx - 1) * rad;
|
||||
double z0 = (fz - 1) * rad;
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
double x3 = (fx + 2) * rad;
|
||||
double z3 = (fz + 2) * rad;
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
//@builder
|
||||
@@ -399,17 +403,17 @@ public class IrisInterpolation {
|
||||
//@done
|
||||
}
|
||||
|
||||
public static double getBicubicBezierNoise(int x, int z, double rad, NoiseProvider n) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x0 = (int) Math.round((fx - 1) * rad);
|
||||
int z0 = (int) Math.round((fz - 1) * rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
int x3 = (int) Math.round((fx + 2) * rad);
|
||||
int z3 = (int) Math.round((fz + 2) * rad);
|
||||
public static double getBicubicBezierNoise(double x, double z, double rad, NoiseProvider n) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x0 = (fx - 1) * rad;
|
||||
double z0 = (fz - 1) * rad;
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
double x3 = (fx + 2) * rad;
|
||||
double z3 = (fz + 2) * rad;
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
//@builder
|
||||
@@ -434,17 +438,17 @@ public class IrisInterpolation {
|
||||
//@done
|
||||
}
|
||||
|
||||
public static double getBicubicParametricNoise(int x, int z, double rad, NoiseProvider n, double a) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x0 = (int) Math.round((fx - 1) * rad);
|
||||
int z0 = (int) Math.round((fz - 1) * rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
int x3 = (int) Math.round((fx + 2) * rad);
|
||||
int z3 = (int) Math.round((fz + 2) * rad);
|
||||
public static double getBicubicParametricNoise(double x, double z, double rad, NoiseProvider n, double a) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x0 = (fx - 1) * rad;
|
||||
double z0 = (fz - 1) * rad;
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
double x3 = (fx + 2) * rad;
|
||||
double z3 = (fz + 2) * rad;
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
//@builder
|
||||
@@ -469,29 +473,29 @@ public class IrisInterpolation {
|
||||
//@done
|
||||
}
|
||||
|
||||
public static double getHermiteNoise(int x, int z, double rad, NoiseProvider n) {
|
||||
public static double getHermiteNoise(double x, double z, double rad, NoiseProvider n) {
|
||||
return getHermiteNoise(x, z, rad, n, 0.5, 0);
|
||||
}
|
||||
|
||||
public static double getHermiteBezierNoise(int x, int z, double rad, NoiseProvider n) {
|
||||
public static double getHermiteBezierNoise(double x, double z, double rad, NoiseProvider n) {
|
||||
return getHermiteBezierNoise(x, z, rad, n, 0.5, 0);
|
||||
}
|
||||
|
||||
public static double getHermiteParametricNoise(int x, int z, double rad, NoiseProvider n, double a) {
|
||||
public static double getHermiteParametricNoise(double x, double z, double rad, NoiseProvider n, double a) {
|
||||
return getHermiteParametricNoise(x, z, rad, n, 0.5, 0, a);
|
||||
}
|
||||
|
||||
public static double getHermiteNoise(int x, int z, double rad, NoiseProvider n, double t, double b) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x0 = (int) Math.round((fx - 1) * rad);
|
||||
int z0 = (int) Math.round((fz - 1) * rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
int x3 = (int) Math.round((fx + 2) * rad);
|
||||
int z3 = (int) Math.round((fz + 2) * rad);
|
||||
public static double getHermiteNoise(double x, double z, double rad, NoiseProvider n, double t, double b) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x0 = (fx - 1) * rad;
|
||||
double z0 = (fz - 1) * rad;
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
double x3 = (fx + 2) * rad;
|
||||
double z3 = (fz + 2) * rad;
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
//@builder
|
||||
@@ -516,17 +520,17 @@ public class IrisInterpolation {
|
||||
//@done
|
||||
}
|
||||
|
||||
public static double getHermiteBezierNoise(int x, int z, double rad, NoiseProvider n, double t, double b) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x0 = (int) Math.round((fx - 1) * rad);
|
||||
int z0 = (int) Math.round((fz - 1) * rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
int x3 = (int) Math.round((fx + 2) * rad);
|
||||
int z3 = (int) Math.round((fz + 2) * rad);
|
||||
public static double getHermiteBezierNoise(double x, double z, double rad, NoiseProvider n, double t, double b) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x0 = (fx - 1) * rad;
|
||||
double z0 = (fz - 1) * rad;
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
double x3 = (fx + 2) * rad;
|
||||
double z3 = (fz + 2) * rad;
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
//@builder
|
||||
@@ -551,17 +555,17 @@ public class IrisInterpolation {
|
||||
//@done
|
||||
}
|
||||
|
||||
public static double getHermiteParametricNoise(int x, int z, double rad, NoiseProvider n, double t, double b, double a) {
|
||||
int fx = getRadiusFactor(x, rad);
|
||||
int fz = getRadiusFactor(z, rad);
|
||||
int x0 = (int) Math.round((fx - 1) * rad);
|
||||
int z0 = (int) Math.round((fz - 1) * rad);
|
||||
int x1 = (int) Math.round(fx * rad);
|
||||
int z1 = (int) Math.round(fz * rad);
|
||||
int x2 = (int) Math.round((fx + 1) * rad);
|
||||
int z2 = (int) Math.round((fz + 1) * rad);
|
||||
int x3 = (int) Math.round((fx + 2) * rad);
|
||||
int z3 = (int) Math.round((fz + 2) * rad);
|
||||
public static double getHermiteParametricNoise(double x, double z, double rad, NoiseProvider n, double t, double b, double a) {
|
||||
double fx = Math.floor(x / rad);
|
||||
double fz = Math.floor(z / rad);
|
||||
double x0 = (fx - 1) * rad;
|
||||
double z0 = (fz - 1) * rad;
|
||||
double x1 = fx * rad;
|
||||
double z1 = fz * rad;
|
||||
double x2 = (fx + 1) * rad;
|
||||
double z2 = (fz + 1) * rad;
|
||||
double x3 = (fx + 2) * rad;
|
||||
double z3 = (fz + 2) * rad;
|
||||
double px = rangeScale(0, 1, x1, x2, x);
|
||||
double pz = rangeScale(0, 1, z1, z2, z);
|
||||
//@builder
|
||||
@@ -601,7 +605,7 @@ public class IrisInterpolation {
|
||||
return rad.get();
|
||||
}
|
||||
|
||||
public static double getNoise(InterpolationMethod method, int x, int z, double h, NoiseProvider noise) {
|
||||
public static double getNoise(InterpolationMethod method, double x, double z, double h, NoiseProvider noise) {
|
||||
if (usesSampleCache(method)) {
|
||||
NoiseSampleCache2D cache = NOISE_SAMPLE_CACHE_2D.get();
|
||||
if (!cache.isInUse()) {
|
||||
@@ -620,37 +624,37 @@ public class IrisInterpolation {
|
||||
return dispatch(method, x, z, h, noise);
|
||||
}
|
||||
|
||||
private static double dispatch(InterpolationMethod method, int x, int z, double h, NoiseProvider n) {
|
||||
private static double dispatch(InterpolationMethod method, double x, double z, double h, NoiseProvider n) {
|
||||
return switch (method) {
|
||||
case BILINEAR -> getBilinearNoise(x, z, h, n);
|
||||
case STARCAST_3 -> Starcast.starcast(x, z, h, 3D, n);
|
||||
case STARCAST_6 -> Starcast.starcast(x, z, h, 6D, n);
|
||||
case STARCAST_9 -> Starcast.starcast(x, z, h, 9D, n);
|
||||
case STARCAST_12 -> Starcast.starcast(x, z, h, 12D, n);
|
||||
case STARCAST_3 -> starcast(x, z, h, 3, n);
|
||||
case STARCAST_6 -> starcast(x, z, h, 6, n);
|
||||
case STARCAST_9 -> starcast(x, z, h, 9, n);
|
||||
case STARCAST_12 -> starcast(x, z, h, 12, n);
|
||||
case BILINEAR_STARCAST_3 ->
|
||||
Starcast.starcast(x, z, h, 3D, (xx, zz) -> getBilinearNoise((int) xx, (int) zz, h, n));
|
||||
starcast(x, z, h, 3, (xx, zz) -> getBilinearNoise(xx, zz, h, n));
|
||||
case BILINEAR_STARCAST_6 ->
|
||||
Starcast.starcast(x, z, h, 6D, (xx, zz) -> getBilinearNoise((int) xx, (int) zz, h, n));
|
||||
starcast(x, z, h, 6, (xx, zz) -> getBilinearNoise(xx, zz, h, n));
|
||||
case BILINEAR_STARCAST_9 ->
|
||||
Starcast.starcast(x, z, h, 9D, (xx, zz) -> getBilinearNoise((int) xx, (int) zz, h, n));
|
||||
starcast(x, z, h, 9, (xx, zz) -> getBilinearNoise(xx, zz, h, n));
|
||||
case BILINEAR_STARCAST_12 ->
|
||||
Starcast.starcast(x, z, h, 12D, (xx, zz) -> getBilinearNoise((int) xx, (int) zz, h, n));
|
||||
starcast(x, z, h, 12, (xx, zz) -> getBilinearNoise(xx, zz, h, n));
|
||||
case HERMITE_STARCAST_3 ->
|
||||
Starcast.starcast(x, z, h, 3D, (xx, zz) -> getHermiteNoise((int) xx, (int) zz, h, n, 0D, 0D));
|
||||
starcast(x, z, h, 3, (xx, zz) -> getHermiteNoise(xx, zz, h, n, 0D, 0D));
|
||||
case HERMITE_STARCAST_6 ->
|
||||
Starcast.starcast(x, z, h, 6D, (xx, zz) -> getHermiteNoise((int) xx, (int) zz, h, n, 0D, 0D));
|
||||
starcast(x, z, h, 6, (xx, zz) -> getHermiteNoise(xx, zz, h, n, 0D, 0D));
|
||||
case HERMITE_STARCAST_9 ->
|
||||
Starcast.starcast(x, z, h, 9D, (xx, zz) -> getHermiteNoise((int) xx, (int) zz, h, n, 0D, 0D));
|
||||
starcast(x, z, h, 9, (xx, zz) -> getHermiteNoise(xx, zz, h, n, 0D, 0D));
|
||||
case HERMITE_STARCAST_12 ->
|
||||
Starcast.starcast(x, z, h, 12D, (xx, zz) -> getHermiteNoise((int) xx, (int) zz, h, n, 0D, 0D));
|
||||
starcast(x, z, h, 12, (xx, zz) -> getHermiteNoise(xx, zz, h, n, 0D, 0D));
|
||||
case BILINEAR_BEZIER -> getBilinearBezierNoise(x, z, h, n);
|
||||
case BILINEAR_PARAMETRIC_2 -> getBilinearParametricNoise(x, z, h, n, 2);
|
||||
case BILINEAR_PARAMETRIC_4 -> getBilinearParametricNoise(x, z, h, n, 4);
|
||||
case BILINEAR_PARAMETRIC_1_5 -> getBilinearParametricNoise(x, z, h, n, 1.5);
|
||||
case BICUBIC -> getBilinearNoise(x, z, h, n);
|
||||
case BICUBIC -> getBicubicNoise(x, z, h, n);
|
||||
case HERMITE -> getHermiteNoise(x, z, h, n);
|
||||
case HERMITE_TENSE -> getHermiteNoise(x, z, h, n, 0.8D, 0D);
|
||||
case CATMULL_ROM_SPLINE -> getHermiteNoise(x, z, h, n, 1D, 0D);
|
||||
case CATMULL_ROM_SPLINE -> getHermiteNoise(x, z, h, n, 0D, 0D);
|
||||
case HERMITE_LOOSE -> getHermiteNoise(x, z, h, n, 0D, 0D);
|
||||
case HERMITE_LOOSE_HALF_NEGATIVE_BIAS -> getHermiteNoise(x, z, h, n, 0D, -0.5D);
|
||||
case HERMITE_LOOSE_HALF_POSITIVE_BIAS -> getHermiteNoise(x, z, h, n, 0D, 0.5D);
|
||||
@@ -660,7 +664,7 @@ public class IrisInterpolation {
|
||||
};
|
||||
}
|
||||
|
||||
public static NoiseBounds getNoiseBounds(InterpolationMethod method, int x, int z, double h, NoiseBoundsProvider noise) {
|
||||
public static NoiseBounds getNoiseBounds(InterpolationMethod method, double x, double z, double h, NoiseBoundsProvider noise) {
|
||||
NoiseBoundsSampleCache2D cache = NOISE_BOUNDS_SAMPLE_CACHE_2D.get();
|
||||
if (cache.isInUse()) {
|
||||
// Nested bounds interpolation: a fresh table on the rare nested path, never the
|
||||
@@ -687,6 +691,32 @@ public class IrisInterpolation {
|
||||
}
|
||||
}
|
||||
|
||||
private static double[][] createStarcastOffsets() {
|
||||
double[][] offsets = new double[4][];
|
||||
for (int index = 0; index < offsets.length; index++) {
|
||||
int checks = (index + 1) * 3;
|
||||
double[] samples = new double[checks * 2];
|
||||
for (int sample = 0; sample < checks; sample++) {
|
||||
double angle = sample * (Math.PI * 2D / checks);
|
||||
double sin = Math.sin(angle);
|
||||
double cos = Math.cos(angle);
|
||||
samples[sample * 2] = cos - sin;
|
||||
samples[sample * 2 + 1] = sin + cos;
|
||||
}
|
||||
offsets[index] = samples;
|
||||
}
|
||||
return offsets;
|
||||
}
|
||||
|
||||
private static double starcast(double x, double z, double radius, int checks, NoiseProvider noise) {
|
||||
double[] offsets = STARCAST_OFFSETS[checks / 3 - 1];
|
||||
double sum = 0D;
|
||||
for (int sample = 0; sample < offsets.length; sample += 2) {
|
||||
sum += noise.noise(x + radius * offsets[sample], z + radius * offsets[sample + 1]);
|
||||
}
|
||||
return sum / checks;
|
||||
}
|
||||
|
||||
private static boolean usesSampleCache(InterpolationMethod method) {
|
||||
return switch (method) {
|
||||
case BILINEAR_STARCAST_3,
|
||||
|
||||
@@ -39,6 +39,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@@ -79,6 +80,7 @@ public class CNG {
|
||||
private transient double signedFractureScale;
|
||||
private transient boolean fastPathStateDirty = true;
|
||||
private transient int coordCacheSalt;
|
||||
private transient Object coordCacheIdentity = new Object();
|
||||
|
||||
public CNG(RNG random) {
|
||||
this(random, 1);
|
||||
@@ -93,7 +95,7 @@ public class CNG {
|
||||
}
|
||||
|
||||
public CNG(RNG random, NoiseType type, double opacity, int octaves) {
|
||||
this(random, type.create(random.nextParallelRNG((long) ((1113334944L * opacity) + 12922 + octaves)).lmax()), opacity, octaves);
|
||||
this(random, type.create(random.nextParallelRNG((long) ((1113334944L * opacity) + 12923)).lmax()), opacity, octaves);
|
||||
}
|
||||
|
||||
public CNG(RNG random, NoiseGenerator generator, double opacity, int octaves) {
|
||||
@@ -115,8 +117,8 @@ public class CNG {
|
||||
this.injectorMode = InjectorMode.ADD;
|
||||
coordCacheSalt = createCoordCacheSalt();
|
||||
|
||||
if (generator instanceof OctaveNoise) {
|
||||
((OctaveNoise) generator).setOctaves(octaves);
|
||||
if (generator instanceof OctaveNoise octaveNoise) {
|
||||
octaveNoise.setOctaves(octaves);
|
||||
}
|
||||
|
||||
refreshFastPathState();
|
||||
@@ -256,7 +258,7 @@ public class CNG {
|
||||
return this;
|
||||
}
|
||||
|
||||
cache = null;
|
||||
markFastPathStateDirty();
|
||||
|
||||
File f = new File(new File(cacheFolder, ".cache"), key + ".cnm");
|
||||
FloatCache fbc;
|
||||
@@ -306,6 +308,7 @@ public class CNG {
|
||||
}
|
||||
|
||||
cache = fbc;
|
||||
coordCacheIdentity = new Object();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -355,6 +358,16 @@ public class CNG {
|
||||
return this;
|
||||
}
|
||||
|
||||
public CNG zoom(double factor) {
|
||||
if (!Double.isFinite(factor) || factor <= 0D || !Double.isFinite(1D / factor)) {
|
||||
throw new IllegalArgumentException("Zoom must be positive and finite");
|
||||
}
|
||||
if (factor != 1D) {
|
||||
zoom(factor, new IdentityHashMap<>());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public CNG patch(double c) {
|
||||
patch = c;
|
||||
markFastPathStateDirty();
|
||||
@@ -650,46 +663,16 @@ public class CNG {
|
||||
return IrisInterpolation.lerp(min, max, noise);
|
||||
}
|
||||
|
||||
private double getNoise(double... dim) {
|
||||
ensureFastPathState();
|
||||
double scale = effectiveScale;
|
||||
|
||||
if (fracture == null || noscale) {
|
||||
return generator.noise(
|
||||
(dim.length > 0 ? dim[0] : 0D) * scale,
|
||||
(dim.length > 1 ? dim[1] : 0D) * scale,
|
||||
(dim.length > 2 ? dim[2] : 0D) * scale) * opacity;
|
||||
}
|
||||
|
||||
double x = dim.length > 0 ? dim[0] : 0D;
|
||||
double y = dim.length > 1 ? dim[1] : 0D;
|
||||
double z = dim.length > 2 ? dim[2] : 0D;
|
||||
|
||||
if (dim.length > 0) {
|
||||
x += (fracture.noise(dim) - 0.5) * fscale;
|
||||
}
|
||||
|
||||
if (dim.length > 1) {
|
||||
y += (fracture.noise(dim[1], dim[0]) - 0.5) * fscale;
|
||||
}
|
||||
|
||||
if (dim.length > 2) {
|
||||
z += (fracture.noise(dim[2], dim[0], dim[1]) - 0.5) * fscale;
|
||||
}
|
||||
|
||||
return generator.noise(x * scale, y * scale, z * scale) * opacity;
|
||||
}
|
||||
|
||||
private double getNoise(double x) {
|
||||
ensureFastPathState();
|
||||
double scl = effectiveScale;
|
||||
|
||||
if (fracture == null || noscale) {
|
||||
return generator.noise(x * scl, 0D, 0D) * opacity;
|
||||
return generator.noise(x * scl) * opacity;
|
||||
}
|
||||
|
||||
double fx = x + ((fracture.noiseFast1D(x) - 0.5D) * fscale);
|
||||
return generator.noise(fx * scl, 0D, 0D) * opacity;
|
||||
return generator.noise(fx * scl) * opacity;
|
||||
}
|
||||
|
||||
private double getNoise(double x, double z) {
|
||||
@@ -697,12 +680,12 @@ public class CNG {
|
||||
double scl = effectiveScale;
|
||||
|
||||
if (fracture == null || noscale) {
|
||||
return generator.noise(x * scl, z * scl, 0D) * opacity;
|
||||
return generator.noise(x * scl, z * scl) * opacity;
|
||||
}
|
||||
|
||||
double fx = x + ((fracture.noiseFast2D(x, z) - 0.5D) * fscale);
|
||||
double fz = z + ((fracture.noiseFast2D(z, x) - 0.5D) * fscale);
|
||||
return generator.noise(fx * scl, fz * scl, 0D) * opacity;
|
||||
return generator.noise(fx * scl, fz * scl) * opacity;
|
||||
}
|
||||
|
||||
private double getNoise(double x, double y, double z) {
|
||||
@@ -735,8 +718,15 @@ public class CNG {
|
||||
return (noise(dim) * 2) - 1;
|
||||
}
|
||||
|
||||
private static boolean isWholeCoordinate(double value) {
|
||||
return value == Math.rint(value);
|
||||
private boolean isCachedCoordinate(double x, double z) {
|
||||
return cache != null
|
||||
&& x >= 0D && x < cache.getWidth()
|
||||
&& z >= 0D && z < cache.getHeight()
|
||||
&& x == (int) x && z == (int) z;
|
||||
}
|
||||
|
||||
private double getCachedNoise(double x, double z) {
|
||||
return cache.get((int) z * cache.getWidth() + (int) x);
|
||||
}
|
||||
|
||||
private double applyPost(double n, double x) {
|
||||
@@ -860,57 +850,12 @@ public class CNG {
|
||||
}
|
||||
|
||||
public double noise(double... dim) {
|
||||
if (dim.length == 1) {
|
||||
return noise(dim[0]);
|
||||
}
|
||||
|
||||
if (dim.length == 2) {
|
||||
return noise(dim[0], dim[1]);
|
||||
}
|
||||
|
||||
if (dim.length == 3) {
|
||||
return noise(dim[0], dim[1], dim[2]);
|
||||
}
|
||||
|
||||
double n = getNoise(dim);
|
||||
n = power != 1D ? (n < 0 ? -Math.pow(Math.abs(n), power) : Math.pow(n, power)) : n;
|
||||
double m = 1;
|
||||
if (children == null) {
|
||||
return (n - down + up) * patch;
|
||||
}
|
||||
|
||||
for (CNG i : children) {
|
||||
double source = n;
|
||||
double value = i.noise(dim);
|
||||
switch (injectorMode) {
|
||||
case ADD -> {
|
||||
n = source + value;
|
||||
m += 1D;
|
||||
}
|
||||
case SRC_SUBTRACT -> {
|
||||
n = source - value < 0D ? 0D : source - value;
|
||||
m -= 1D;
|
||||
}
|
||||
case DST_SUBTRACT -> {
|
||||
n = value - source < 0D ? 0D : source - value;
|
||||
m -= 1D;
|
||||
}
|
||||
case MULTIPLY -> n = source * value;
|
||||
case MAX -> n = Math.max(source, value);
|
||||
case MIN -> n = Math.min(source, value);
|
||||
case SRC_MOD -> n = source % value;
|
||||
case SRC_POW -> n = Math.pow(source, value);
|
||||
case DST_MOD -> n = value % source;
|
||||
case DST_POW -> n = Math.pow(value, source);
|
||||
case CUSTOM -> {
|
||||
double[] combined = injector.combine(source, value);
|
||||
n = combined[0];
|
||||
m += combined[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ((n / m) - down + up) * patch;
|
||||
return switch (dim.length) {
|
||||
case 1 -> noise(dim[0]);
|
||||
case 2 -> noise(dim[0], dim[1]);
|
||||
case 3 -> noise(dim[0], dim[1], dim[2]);
|
||||
default -> throw new IllegalArgumentException("Noise requires one, two, or three coordinates");
|
||||
};
|
||||
}
|
||||
|
||||
public double noise(double x) {
|
||||
@@ -922,16 +867,16 @@ public class CNG {
|
||||
}
|
||||
|
||||
public double noise(double x, double z) {
|
||||
if (cache != null && isWholeCoordinate(x) && isWholeCoordinate(z)) {
|
||||
return cache.get((int) x, (int) z);
|
||||
if (isCachedCoordinate(x, z)) {
|
||||
return getCachedNoise(x, z);
|
||||
}
|
||||
|
||||
return applyPost(getNoise(x, z), x, z);
|
||||
}
|
||||
|
||||
public double noiseFast2D(double x, double z) {
|
||||
if (cache != null && isWholeCoordinate(x) && isWholeCoordinate(z)) {
|
||||
return cache.get((int) x, (int) z);
|
||||
if (isCachedCoordinate(x, z)) {
|
||||
return getCachedNoise(x, z);
|
||||
}
|
||||
|
||||
if (isIdentityPostFastPath()) {
|
||||
@@ -963,12 +908,13 @@ public class CNG {
|
||||
long kx = Double.doubleToRawLongBits(x);
|
||||
long kz = Double.doubleToRawLongBits(z);
|
||||
CoordCache cc = COORD_CACHE_2D.get();
|
||||
Object identity = coordCacheIdentity();
|
||||
int slot = coordSlot(kx, kz, coordCacheSalt());
|
||||
if (cc.owner[slot] == this && cc.kx[slot] == kx && cc.kz[slot] == kz) {
|
||||
if (cc.owner[slot] == identity && cc.kx[slot] == kx && cc.kz[slot] == kz) {
|
||||
return cc.value[slot];
|
||||
}
|
||||
double computed = computeNoiseFastSigned2D(x, z);
|
||||
cc.owner[slot] = this;
|
||||
cc.owner[slot] = identity;
|
||||
cc.kx[slot] = kx;
|
||||
cc.kz[slot] = kz;
|
||||
cc.value[slot] = computed;
|
||||
@@ -976,8 +922,8 @@ public class CNG {
|
||||
}
|
||||
|
||||
private double computeNoiseFastSigned2D(double x, double z) {
|
||||
if (cache != null && isWholeCoordinate(x) && isWholeCoordinate(z)) {
|
||||
return (cache.get((int) x, (int) z) * 2D) - 1D;
|
||||
if (isCachedCoordinate(x, z)) {
|
||||
return (getCachedNoise(x, z) * 2D) - 1D;
|
||||
}
|
||||
|
||||
if (hasIdentitySignedFastPath()) {
|
||||
@@ -1014,12 +960,13 @@ public class CNG {
|
||||
long ky = Double.doubleToRawLongBits(y);
|
||||
long kz = Double.doubleToRawLongBits(z);
|
||||
CoordCache3D cc = COORD_CACHE_3D.get();
|
||||
Object identity = coordCacheIdentity();
|
||||
int slot = coordSlot(kx ^ Long.rotateLeft(ky, 21), kz, coordCacheSalt());
|
||||
if (cc.owner[slot] == this && cc.kx[slot] == kx && cc.ky[slot] == ky && cc.kz[slot] == kz) {
|
||||
if (cc.owner[slot] == identity && cc.kx[slot] == kx && cc.ky[slot] == ky && cc.kz[slot] == kz) {
|
||||
return cc.value[slot];
|
||||
}
|
||||
double computed = hasIdentitySignedFastPath() ? getSignedNoise(x, y, z) : (noiseFast3D(x, y, z) * 2D) - 1D;
|
||||
cc.owner[slot] = this;
|
||||
cc.owner[slot] = identity;
|
||||
cc.kx[slot] = kx;
|
||||
cc.ky[slot] = ky;
|
||||
cc.kz[slot] = kz;
|
||||
@@ -1034,7 +981,15 @@ public class CNG {
|
||||
}
|
||||
|
||||
public CNG oct(int octaves) {
|
||||
if (oct == octaves) {
|
||||
return this;
|
||||
}
|
||||
|
||||
oct = octaves;
|
||||
if (generator instanceof OctaveNoise octaveNoise) {
|
||||
octaveNoise.setOctaves(octaves);
|
||||
}
|
||||
markFastPathStateDirty();
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1056,6 +1011,23 @@ public class CNG {
|
||||
return identitySignedFastPath;
|
||||
}
|
||||
|
||||
private void zoom(double factor, IdentityHashMap<CNG, Boolean> visited) {
|
||||
if (visited.put(this, Boolean.TRUE) != null) {
|
||||
return;
|
||||
}
|
||||
bakedScale /= factor;
|
||||
fscale *= factor;
|
||||
if (fracture != null) {
|
||||
fracture.zoom(factor, visited);
|
||||
}
|
||||
if (children != null) {
|
||||
for (CNG child : children) {
|
||||
child.zoom(factor, visited);
|
||||
}
|
||||
}
|
||||
markFastPathStateDirty();
|
||||
}
|
||||
|
||||
private void ensureFastPathState() {
|
||||
if (fastPathStateDirty) {
|
||||
refreshFastPathState();
|
||||
@@ -1064,6 +1036,16 @@ public class CNG {
|
||||
|
||||
private void markFastPathStateDirty() {
|
||||
fastPathStateDirty = true;
|
||||
cache = null;
|
||||
coordCacheIdentity = new Object();
|
||||
}
|
||||
|
||||
private Object coordCacheIdentity() {
|
||||
if (coordCacheIdentity == null) {
|
||||
coordCacheIdentity = new Object();
|
||||
}
|
||||
|
||||
return coordCacheIdentity;
|
||||
}
|
||||
|
||||
private int coordCacheSalt() {
|
||||
@@ -1112,12 +1094,12 @@ public class CNG {
|
||||
CNG localFracture = fracture;
|
||||
|
||||
if (localFracture == null || noscale) {
|
||||
return signedWithOpacity(localGenerator.noiseSigned(x * scl, z * scl, 0D));
|
||||
return signedWithOpacity(localGenerator.noiseSigned(x * scl, z * scl));
|
||||
}
|
||||
|
||||
double fx = x + (localFracture.noiseFastSigned2D(x, z) * signedFractureScale);
|
||||
double fz = z + (localFracture.noiseFastSigned2D(z, x) * signedFractureScale);
|
||||
return signedWithOpacity(localGenerator.noiseSigned(fx * scl, fz * scl, 0D));
|
||||
return signedWithOpacity(localGenerator.noiseSigned(fx * scl, fz * scl));
|
||||
}
|
||||
|
||||
private double getSignedNoise(double x, double y, double z) {
|
||||
|
||||
@@ -32,7 +32,7 @@ public class CellHeightNoise implements NoiseGenerator {
|
||||
}
|
||||
|
||||
private double filter(double noise) {
|
||||
return M.clip(1D - ((noise / 2D) + 0.5D), 0D, 1D);
|
||||
return M.clip((noise / 2D) + 0.5D, 0D, 1D);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,27 +21,27 @@ package art.arcane.iris.util.project.noise;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
|
||||
public class CellularNoise implements NoiseGenerator {
|
||||
private final FastNoise n;
|
||||
private final FastNoiseDouble n;
|
||||
|
||||
public CellularNoise(long seed) {
|
||||
this.n = new FastNoise(new RNG(seed).imax());
|
||||
n.SetNoiseType(FastNoise.NoiseType.Cellular);
|
||||
n.SetCellularReturnType(FastNoise.CellularReturnType.CellValue);
|
||||
n.SetCellularDistanceFunction(FastNoise.CellularDistanceFunction.Natural);
|
||||
this.n = new FastNoiseDouble(new RNG(seed).lmax());
|
||||
n.setNoiseType(FastNoiseDouble.NoiseType.Cellular);
|
||||
n.setCellularReturnType(FastNoiseDouble.CellularReturnType.CellValue);
|
||||
n.setCellularDistanceFunction(FastNoiseDouble.CellularDistanceFunction.Natural);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
return (n.GetCellular((float) x, 0) / 2D) + 0.5D;
|
||||
return (n.GetCellular(x, 0) / 2D) + 0.5D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
return (n.GetCellular((float) x, (float) z) / 2D) + 0.5D;
|
||||
return (n.GetCellular(x, z) / 2D) + 0.5D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
return (n.GetCellular((float) x, (float) y, (float) z) / 2D) + 0.5D;
|
||||
return (n.GetCellular(x, y, z) / 2D) + 0.5D;
|
||||
}
|
||||
}
|
||||
@@ -39,10 +39,6 @@ public class CloverNoise implements NoiseGenerator {
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
if (z == 0) {
|
||||
return n2.noise(x, y);
|
||||
}
|
||||
|
||||
return n3.noise(x, y, z);
|
||||
}
|
||||
|
||||
@@ -129,8 +125,6 @@ public class CloverNoise implements NoiseGenerator {
|
||||
Vector2 p_floor = p.floor();
|
||||
|
||||
Vector2 c_11 = offset(p_floor);
|
||||
Vector2 c_10 = offset(p_floor.add(0, -1));
|
||||
Vector2 c_12 = offset(p_floor.add(0, 1));
|
||||
Vector2 c_01 = offset(p_floor.add(-1, 0));
|
||||
Vector2 c_21 = offset(p_floor.add(1, 0));
|
||||
|
||||
@@ -143,6 +137,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
Vector2 a, c, d;
|
||||
|
||||
if (side_nx < 0 && p.x < c_11.x || side_px > 0 && p.x > c_11.x) {
|
||||
Vector2 c_12 = offset(p_floor.add(0, 1));
|
||||
double side_py = m_p_c11.sub(d_p_c11.mult(c_12)).ymx();
|
||||
|
||||
if (side_py > 0) {
|
||||
@@ -155,6 +150,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
d = new Vector2(1, 1);
|
||||
}
|
||||
} else {
|
||||
Vector2 c_10 = offset(p_floor.add(0, -1));
|
||||
double side_ny = m_p_c11.sub(d_p_c11.mult(c_10)).ymx();
|
||||
|
||||
if (side_ny > 0) {
|
||||
@@ -235,6 +231,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
* @return The value of noise, from 0 to 1.
|
||||
*/
|
||||
public double fractalNoise(Vector2 p, int iterations) {
|
||||
iterations = Math.max(1, Math.min(16, iterations));
|
||||
double total = 0;
|
||||
double weight = 1;
|
||||
double div = 0;
|
||||
@@ -382,6 +379,18 @@ public class CloverNoise implements NoiseGenerator {
|
||||
private static final long HASH_M = 0x1000000000000L;
|
||||
private static final double POINT_SPREAD = 0.2;
|
||||
private static final double CURL_DX = 0.0001;
|
||||
private static final double[] HEIGHT_SINES = new double[1000];
|
||||
private static final double[] HEIGHT_COSINES = new double[1000];
|
||||
private static final ThreadLocal<Vector3[]> SAMPLE_VERTICES = ThreadLocal.withInitial(Noise3D::createSampleVertices);
|
||||
|
||||
static {
|
||||
for (int index = 0; index < HEIGHT_SINES.length; index++) {
|
||||
double height = (((index + 0.5D) / 100D) % 1D - 0.5D) * Math.PI / 2D;
|
||||
HEIGHT_SINES[index] = Math.sin(height);
|
||||
HEIGHT_COSINES[index] = Math.cos(height);
|
||||
}
|
||||
}
|
||||
|
||||
private final long seed;
|
||||
|
||||
public Noise3D(long seed) {
|
||||
@@ -392,6 +401,14 @@ public class CloverNoise implements NoiseGenerator {
|
||||
this(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
private static Vector3[] createSampleVertices() {
|
||||
Vector3[] vertices = new Vector3[21];
|
||||
for (int index = 0; index < vertices.length; index++) {
|
||||
vertices[index] = new Vector3();
|
||||
}
|
||||
return vertices;
|
||||
}
|
||||
|
||||
private long doHash(long input, long seed) {
|
||||
input += seed;
|
||||
|
||||
@@ -433,27 +450,23 @@ public class CloverNoise implements NoiseGenerator {
|
||||
return (double) hash / HASH_M;
|
||||
}
|
||||
|
||||
private Vector3 offset(Vector3 position) {
|
||||
return offset(position.x, position.y, position.z);
|
||||
private Vector3 offset(Vector3 destination, Vector3 position, double xOffset, double yOffset, double zOffset) {
|
||||
return offset(destination, position.x + xOffset, position.y + yOffset, position.z + zOffset);
|
||||
}
|
||||
|
||||
private Vector3 offset(Vector3 position, double xOffset, double yOffset, double zOffset) {
|
||||
return offset(position.x + xOffset, position.y + yOffset, position.z + zOffset);
|
||||
}
|
||||
|
||||
private Vector3 offset(double positionX, double positionY, double positionZ) {
|
||||
private Vector3 offset(Vector3 destination, double positionX, double positionY, double positionZ) {
|
||||
double hash = hash(positionX, positionY, positionZ);
|
||||
double theta = hash * Math.PI * 2000;
|
||||
double height = (((Math.floor(hash * 1000) + 0.5) / 100) % 1 - 0.5) * Math.PI / 2;
|
||||
int heightIndex = (int) (hash * 1000D);
|
||||
double layer = Math.floor(hash * 10 + 1) / 10;
|
||||
double cosHeight = Math.cos(height);
|
||||
double cosHeight = HEIGHT_COSINES[heightIndex];
|
||||
double offsetX = Math.sin(theta) * cosHeight * layer + 0.5;
|
||||
double offsetY = Math.sin(height) * layer + 0.5;
|
||||
double offsetY = HEIGHT_SINES[heightIndex] * layer + 0.5;
|
||||
double offsetZ = Math.cos(theta) * cosHeight * layer + 0.5;
|
||||
return new Vector3(
|
||||
positionX + (offsetX * (POINT_SPREAD * 2) + (0.5 - POINT_SPREAD)),
|
||||
positionY + (offsetY * (POINT_SPREAD * 2) + (0.5 - POINT_SPREAD)),
|
||||
positionZ + (offsetZ * (POINT_SPREAD * 2) + (0.5 - POINT_SPREAD)));
|
||||
destination.x = positionX + (offsetX * (POINT_SPREAD * 2) + (0.5 - POINT_SPREAD));
|
||||
destination.y = positionY + (offsetY * (POINT_SPREAD * 2) + (0.5 - POINT_SPREAD));
|
||||
destination.z = positionZ + (offsetZ * (POINT_SPREAD * 2) + (0.5 - POINT_SPREAD));
|
||||
return destination;
|
||||
}
|
||||
|
||||
private boolean boundary(int permutation, Vector3 p, Vector3 c_00, Vector3 c_10, Vector3 c_20, Vector3 c_01, Vector3 c_11, Vector3 c_21, Vector3 c_02, Vector3 c_12, Vector3 c_22) {
|
||||
@@ -565,27 +578,34 @@ public class CloverNoise implements NoiseGenerator {
|
||||
* @return The value of noise, from 0 to 1.
|
||||
*/
|
||||
public double noise(Vector3 p) {
|
||||
Vector3 p_floor = p.floor();
|
||||
return sample(p, SAMPLE_VERTICES.get());
|
||||
}
|
||||
|
||||
Vector3 c_111 = offset(p_floor);
|
||||
Vector3 c_100 = offset(p_floor, 0, -1, -1);
|
||||
Vector3 c_010 = offset(p_floor, -1, 0, -1);
|
||||
Vector3 c_110 = offset(p_floor, 0, 0, -1);
|
||||
Vector3 c_210 = offset(p_floor, 1, 0, -1);
|
||||
Vector3 c_120 = offset(p_floor, 0, 1, -1);
|
||||
Vector3 c_001 = offset(p_floor, -1, -1, 0);
|
||||
Vector3 c_101 = offset(p_floor, 0, -1, 0);
|
||||
Vector3 c_201 = offset(p_floor, 1, -1, 0);
|
||||
Vector3 c_011 = offset(p_floor, -1, 0, 0);
|
||||
Vector3 c_211 = offset(p_floor, 1, 0, 0);
|
||||
Vector3 c_021 = offset(p_floor, -1, 1, 0);
|
||||
Vector3 c_121 = offset(p_floor, 0, 1, 0);
|
||||
Vector3 c_221 = offset(p_floor, 1, 1, 0);
|
||||
Vector3 c_102 = offset(p_floor, 0, -1, 1);
|
||||
Vector3 c_012 = offset(p_floor, -1, 0, 1);
|
||||
Vector3 c_112 = offset(p_floor, 0, 0, 1);
|
||||
Vector3 c_212 = offset(p_floor, 1, 0, 1);
|
||||
Vector3 c_122 = offset(p_floor, 0, 1, 1);
|
||||
private double sample(Vector3 p, Vector3[] vertices) {
|
||||
Vector3 p_floor = vertices[20];
|
||||
p_floor.x = Math.floor(p.x);
|
||||
p_floor.y = Math.floor(p.y);
|
||||
p_floor.z = Math.floor(p.z);
|
||||
|
||||
Vector3 c_111 = offset(vertices[0], p_floor.x, p_floor.y, p_floor.z);
|
||||
Vector3 c_100 = offset(vertices[1], p_floor, 0, -1, -1);
|
||||
Vector3 c_010 = offset(vertices[2], p_floor, -1, 0, -1);
|
||||
Vector3 c_110 = offset(vertices[3], p_floor, 0, 0, -1);
|
||||
Vector3 c_210 = offset(vertices[4], p_floor, 1, 0, -1);
|
||||
Vector3 c_120 = offset(vertices[5], p_floor, 0, 1, -1);
|
||||
Vector3 c_001 = offset(vertices[6], p_floor, -1, -1, 0);
|
||||
Vector3 c_101 = offset(vertices[7], p_floor, 0, -1, 0);
|
||||
Vector3 c_201 = offset(vertices[8], p_floor, 1, -1, 0);
|
||||
Vector3 c_011 = offset(vertices[9], p_floor, -1, 0, 0);
|
||||
Vector3 c_211 = offset(vertices[10], p_floor, 1, 0, 0);
|
||||
Vector3 c_021 = offset(vertices[11], p_floor, -1, 1, 0);
|
||||
Vector3 c_121 = offset(vertices[12], p_floor, 0, 1, 0);
|
||||
Vector3 c_221 = offset(vertices[13], p_floor, 1, 1, 0);
|
||||
Vector3 c_102 = offset(vertices[14], p_floor, 0, -1, 1);
|
||||
Vector3 c_012 = offset(vertices[15], p_floor, -1, 0, 1);
|
||||
Vector3 c_112 = offset(vertices[16], p_floor, 0, 0, 1);
|
||||
Vector3 c_212 = offset(vertices[17], p_floor, 1, 0, 1);
|
||||
Vector3 c_122 = offset(vertices[18], p_floor, 0, 1, 1);
|
||||
|
||||
boolean x_bound = boundary(1, p, c_100, c_110, c_120, c_101, c_111, c_121, c_102, c_112, c_122);
|
||||
boolean y_bound = boundary(2, p, c_010, c_110, c_210, c_011, c_111, c_211, c_012, c_112, c_212);
|
||||
@@ -596,7 +616,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
if (x_bound) {
|
||||
if (y_bound) {
|
||||
if (z_bound) {
|
||||
a = offset(p_floor, -1, -1, -1);
|
||||
a = offset(vertices[19], p_floor, -1, -1, -1);
|
||||
b = c_001;
|
||||
c = c_010;
|
||||
d = c_011;
|
||||
@@ -606,7 +626,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
h = c_111;
|
||||
} else {
|
||||
a = c_001;
|
||||
b = offset(p_floor, -1, -1, 1);
|
||||
b = offset(vertices[19], p_floor, -1, -1, 1);
|
||||
c = c_011;
|
||||
d = c_012;
|
||||
e = c_101;
|
||||
@@ -618,7 +638,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
if (z_bound) {
|
||||
a = c_010;
|
||||
b = c_011;
|
||||
c = offset(p_floor, -1, 1, -1);
|
||||
c = offset(vertices[19], p_floor, -1, 1, -1);
|
||||
d = c_021;
|
||||
e = c_110;
|
||||
f = c_111;
|
||||
@@ -628,7 +648,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
a = c_011;
|
||||
b = c_012;
|
||||
c = c_021;
|
||||
d = offset(p_floor, -1, 1, 1);
|
||||
d = offset(vertices[19], p_floor, -1, 1, 1);
|
||||
e = c_111;
|
||||
f = c_112;
|
||||
g = c_121;
|
||||
@@ -642,7 +662,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
b = c_101;
|
||||
c = c_110;
|
||||
d = c_111;
|
||||
e = offset(p_floor, 1, -1, -1);
|
||||
e = offset(vertices[19], p_floor, 1, -1, -1);
|
||||
f = c_201;
|
||||
g = c_210;
|
||||
h = c_211;
|
||||
@@ -652,7 +672,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
c = c_111;
|
||||
d = c_112;
|
||||
e = c_201;
|
||||
f = offset(p_floor, 1, -1, 1);
|
||||
f = offset(vertices[19], p_floor, 1, -1, 1);
|
||||
g = c_211;
|
||||
h = c_212;
|
||||
}
|
||||
@@ -664,7 +684,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
d = c_121;
|
||||
e = c_210;
|
||||
f = c_211;
|
||||
g = offset(p_floor, 1, 1, -1);
|
||||
g = offset(vertices[19], p_floor, 1, 1, -1);
|
||||
h = c_221;
|
||||
} else {
|
||||
a = c_111;
|
||||
@@ -674,7 +694,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
e = c_211;
|
||||
f = c_212;
|
||||
g = c_221;
|
||||
h = offset(p_floor, 1, 1, 1);
|
||||
h = offset(vertices[19], p_floor, 1, 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -783,6 +803,7 @@ public class CloverNoise implements NoiseGenerator {
|
||||
* @return The value of noise, from 0 to 1.
|
||||
*/
|
||||
public double fractalNoise(Vector3 p, int iterations) {
|
||||
iterations = Math.max(1, Math.min(16, iterations));
|
||||
double total = 0;
|
||||
double weight = 1;
|
||||
double div = 0;
|
||||
@@ -980,6 +1001,9 @@ public class CloverNoise implements NoiseGenerator {
|
||||
|
||||
public Vector2 normalize() {
|
||||
double len2 = x * x + y * y;
|
||||
if (len2 == 0D) {
|
||||
return new Vector2(0D, 0D);
|
||||
}
|
||||
double len = Math.sqrt(len2);
|
||||
|
||||
return new Vector2(x / len, y / len);
|
||||
@@ -1092,6 +1116,9 @@ public class CloverNoise implements NoiseGenerator {
|
||||
|
||||
public Vector3 normalize() {
|
||||
double len2 = x * x + y * y + z * z;
|
||||
if (len2 == 0D) {
|
||||
return new Vector3(0D, 0D, 0D);
|
||||
}
|
||||
double len = Math.sqrt(len2);
|
||||
|
||||
return new Vector3(x / len, y / len, z / len);
|
||||
|
||||
@@ -76,7 +76,7 @@ public class FastNoise {
|
||||
}
|
||||
|
||||
private static int FastFloor(float f) {
|
||||
return (f >= 0 ? (int) f : (int) f - 1);
|
||||
return (int) Math.floor(f);
|
||||
}
|
||||
|
||||
private static int FastRound(float f) {
|
||||
@@ -259,7 +259,7 @@ public class FastNoise {
|
||||
// Sets octave count for all fractal noise types
|
||||
// Default: 3
|
||||
public void SetFractalOctaves(int octaves) {
|
||||
m_octaves = octaves;
|
||||
m_octaves = Math.max(1, Math.min(16, octaves));
|
||||
CalculateFractalBounding();
|
||||
}
|
||||
|
||||
@@ -1515,7 +1515,7 @@ public class FastNoise {
|
||||
x *= m_frequency;
|
||||
y *= m_frequency;
|
||||
|
||||
return SingleCubic(0, x, y);
|
||||
return SingleCubic(m_seed, x, y);
|
||||
}
|
||||
|
||||
private float SingleCubic(int seed, float x, float y) {
|
||||
@@ -2194,4 +2194,4 @@ public class FastNoise {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public class FastNoiseDouble {
|
||||
}
|
||||
|
||||
private static long fastFloor(double f) {
|
||||
return (f >= 0 ? (long) f : (long) f - 1);
|
||||
return (long) Math.floor(f);
|
||||
}
|
||||
|
||||
private static long fastRound(double f) {
|
||||
@@ -289,7 +289,7 @@ public class FastNoiseDouble {
|
||||
// Sets octave count for all fractal noise types
|
||||
// Default: 3
|
||||
public void setFractalOctaves(long octaves) {
|
||||
m_octaves = octaves;
|
||||
m_octaves = Math.max(1, Math.min(16, octaves));
|
||||
calculateFractalBounding();
|
||||
}
|
||||
|
||||
@@ -1453,7 +1453,7 @@ public class FastNoiseDouble {
|
||||
x *= m_frequency;
|
||||
y *= m_frequency;
|
||||
|
||||
return SingleCubic(0, x, y);
|
||||
return SingleCubic(m_seed, x, y);
|
||||
}
|
||||
|
||||
private double SingleCubic(long seed, double x, double y) {
|
||||
@@ -1676,14 +1676,11 @@ public class FastNoiseDouble {
|
||||
break;
|
||||
}
|
||||
|
||||
return switch (m_cellularReturnType) {
|
||||
case Distance2 -> distance2 - 1;
|
||||
case Distance2Add -> distance2 + distance - 1;
|
||||
case Distance2Sub -> distance2 - distance - 1;
|
||||
case Distance2Mul -> distance2 * distance - 1;
|
||||
case Distance2Div -> distance / distance2 - 1;
|
||||
default -> 0;
|
||||
};
|
||||
double boundary = 1.55D - Math.max(Math.abs(x - xr), Math.max(Math.abs(y - yr), Math.abs(z - zr)));
|
||||
if (cellularDistance(boundary, 0D, 0D) < distance2) {
|
||||
return refineCellular2Edge(x, y, z, xr, yr, zr, distance, distance2);
|
||||
}
|
||||
return cellular2EdgeResult(distance, distance2);
|
||||
}
|
||||
|
||||
public double GetCellular(double x, double y) {
|
||||
@@ -1856,6 +1853,93 @@ public class FastNoiseDouble {
|
||||
break;
|
||||
}
|
||||
|
||||
double boundary = 1.55D - Math.max(Math.abs(x - xr), Math.abs(y - yr));
|
||||
if (cellularDistance(boundary, 0D, 0D) < distance2) {
|
||||
return refineCellular2Edge(x, y, xr, yr, distance, distance2);
|
||||
}
|
||||
return cellular2EdgeResult(distance, distance2);
|
||||
}
|
||||
|
||||
private double refineCellular2Edge(double x, double y, long xr, long yr, double distance, double distance2) {
|
||||
for (int dx = -2; dx <= 2; dx++) {
|
||||
long xi = xr + dx;
|
||||
double baseX = xi - x;
|
||||
double boundX = Math.max(0D, Math.abs(baseX) - 0.45D);
|
||||
if (cellularDistance(boundX, 0D, 0D) >= distance2) {
|
||||
continue;
|
||||
}
|
||||
for (int dy = -2; dy <= 2; dy++) {
|
||||
if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
|
||||
continue;
|
||||
}
|
||||
long yi = yr + dy;
|
||||
double baseY = yi - y;
|
||||
double boundY = Math.max(0D, Math.abs(baseY) - 0.45D);
|
||||
if (cellularDistance(boundX, boundY, 0D) >= distance2) {
|
||||
continue;
|
||||
}
|
||||
int index = (int) hash2D(m_seed, xi, yi) & 255;
|
||||
double candidate = cellularDistance(baseX + CELL_2D_X[index], baseY + CELL_2D_Y[index], 0D);
|
||||
if (candidate < distance) {
|
||||
distance2 = distance;
|
||||
distance = candidate;
|
||||
} else if (candidate < distance2) {
|
||||
distance2 = candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cellular2EdgeResult(distance, distance2);
|
||||
}
|
||||
|
||||
private double refineCellular2Edge(double x, double y, double z, long xr, long yr, long zr, double distance, double distance2) {
|
||||
int radius = m_cellularDistanceFunction == CellularDistanceFunction.Manhattan ? 3 : 2;
|
||||
for (int dx = -radius; dx <= radius; dx++) {
|
||||
long xi = xr + dx;
|
||||
double baseX = xi - x;
|
||||
double boundX = Math.max(0D, Math.abs(baseX) - 0.45D);
|
||||
if (cellularDistance(boundX, 0D, 0D) >= distance2) {
|
||||
continue;
|
||||
}
|
||||
for (int dy = -radius; dy <= radius; dy++) {
|
||||
long yi = yr + dy;
|
||||
double baseY = yi - y;
|
||||
double boundY = Math.max(0D, Math.abs(baseY) - 0.45D);
|
||||
if (cellularDistance(boundX, boundY, 0D) >= distance2) {
|
||||
continue;
|
||||
}
|
||||
for (int dz = -radius; dz <= radius; dz++) {
|
||||
if (Math.abs(dx) < 2 && Math.abs(dy) < 2 && Math.abs(dz) < 2) {
|
||||
continue;
|
||||
}
|
||||
long zi = zr + dz;
|
||||
double baseZ = zi - z;
|
||||
double boundZ = Math.max(0D, Math.abs(baseZ) - 0.45D);
|
||||
if (cellularDistance(boundX, boundY, boundZ) >= distance2) {
|
||||
continue;
|
||||
}
|
||||
int index = (int) hash3D(m_seed, xi, yi, zi) & 255;
|
||||
double candidate = cellularDistance(baseX + CELL_3D_X[index], baseY + CELL_3D_Y[index], baseZ + CELL_3D_Z[index]);
|
||||
if (candidate < distance) {
|
||||
distance2 = distance;
|
||||
distance = candidate;
|
||||
} else if (candidate < distance2) {
|
||||
distance2 = candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return cellular2EdgeResult(distance, distance2);
|
||||
}
|
||||
|
||||
private double cellularDistance(double x, double y, double z) {
|
||||
return switch (m_cellularDistanceFunction) {
|
||||
case Euclidean -> x * x + y * y + z * z;
|
||||
case Manhattan -> Math.abs(x) + Math.abs(y) + Math.abs(z);
|
||||
case Natural -> (Math.abs(x) + Math.abs(y) + Math.abs(z)) + (x * x + y * y + z * z);
|
||||
};
|
||||
}
|
||||
|
||||
private double cellular2EdgeResult(double distance, double distance2) {
|
||||
return switch (m_cellularReturnType) {
|
||||
case Distance2 -> distance2 - 1;
|
||||
case Distance2Add -> distance2 + distance - 1;
|
||||
|
||||
@@ -25,6 +25,7 @@ public class FractalBillowPerlinNoise implements NoiseGenerator, OctaveNoise {
|
||||
|
||||
public FractalBillowPerlinNoise(long seed) {
|
||||
this.n = new FastNoiseDouble(new RNG(seed).lmax());
|
||||
n.setLongerp(FastNoiseDouble.Longerp.Qulongic);
|
||||
n.setFractalOctaves(1);
|
||||
n.setFractalType(FractalType.Billow);
|
||||
}
|
||||
|
||||
@@ -20,11 +20,12 @@ package art.arcane.iris.util.project.noise;
|
||||
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
import art.arcane.iris.util.project.noise.FastNoiseDouble.FractalType;
|
||||
public class FractalCubicNoise implements NoiseGenerator {
|
||||
public class FractalCubicNoise implements NoiseGenerator, OctaveNoise {
|
||||
private final FastNoiseDouble n;
|
||||
|
||||
public FractalCubicNoise(long seed) {
|
||||
this.n = new FastNoiseDouble(new RNG(seed).lmax());
|
||||
n.setFractalOctaves(1);
|
||||
n.setFractalType(FractalType.Billow);
|
||||
}
|
||||
|
||||
@@ -46,4 +47,9 @@ public class FractalCubicNoise implements NoiseGenerator {
|
||||
public double noise(double x, double y, double z) {
|
||||
return f(n.GetCubicFractal(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOctaves(int octaves) {
|
||||
n.setFractalOctaves(octaves);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -30,7 +30,7 @@ public class FractalRigidMultiSimplexNoise implements NoiseGenerator, OctaveNois
|
||||
}
|
||||
|
||||
public double f(double v) {
|
||||
return (v / 2D) + 0.5D;
|
||||
return 1D + (v - 1D) * n.getFractalBounding();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,294 +2,89 @@ package art.arcane.iris.util.project.noise;
|
||||
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
|
||||
public class HexJamesNoise implements NoiseGenerator, OctaveNoise {
|
||||
private static final double SQRT_3_OVER_3 = Math.sqrt(3.0) / 3.0;
|
||||
private static final double TWO_OVER_THREE = 2.0 / 3.0;
|
||||
private static final double SQRT_3 = Math.sqrt(3.0);
|
||||
private static final double THREE_OVER_TWO = 1.5D;
|
||||
private static final double ONE_THIRD = 1D / 3D;
|
||||
private static final double TWO_THIRDS = 2D / 3D;
|
||||
public class HexJamesNoise extends HexagonalNoise implements OctaveNoise {
|
||||
private static final int MAX_DEPTH = 7;
|
||||
private static final double HEAT_SCALE = 0.31D;
|
||||
private static final double HEAT_SCALE = 18D;
|
||||
private static final double LARGE_CONTINUE = 0.26D;
|
||||
private static final double SMALL_CONTINUE = 0.79D;
|
||||
private static final double CENTER_CONTINUE = 0.58D;
|
||||
private static final long CONST_X = 0x9E3779B97F4A7C15L;
|
||||
private static final long CONST_Z = 0xC2B2AE3D27D4EB4FL;
|
||||
private static final long[][] CHILD_DIRECTIONS = new long[][]{
|
||||
{1L, 0L},
|
||||
{1L, -1L},
|
||||
{0L, -1L},
|
||||
{-1L, 0L},
|
||||
{-1L, 1L},
|
||||
{0L, 1L}
|
||||
};
|
||||
private static final ThreadLocal<HexScratch> SCRATCH = ThreadLocal.withInitial(HexScratch::new);
|
||||
private final long seed;
|
||||
private final SimplexNoise heatSimplex;
|
||||
private int octaves;
|
||||
private final SimplexNoise heat;
|
||||
|
||||
public HexJamesNoise(long seed) {
|
||||
RNG rng = new RNG(seed);
|
||||
this.seed = rng.lmax();
|
||||
this.heatSimplex = new SimplexNoise(rng.nextParallelRNG(877L).lmax());
|
||||
this.octaves = 1;
|
||||
this.heat = new SimplexNoise(rng.nextParallelRNG(877L).lmax());
|
||||
}
|
||||
|
||||
private double clip(double value) {
|
||||
if (value < 0D) {
|
||||
return 0D;
|
||||
}
|
||||
|
||||
if (value > 1D) {
|
||||
return 1D;
|
||||
}
|
||||
|
||||
return value;
|
||||
@Override
|
||||
public void setOctaves(int octaves) {
|
||||
heat.setOctaves(octaves);
|
||||
}
|
||||
|
||||
private long mix(long input) {
|
||||
input = (input ^ (input >>> 33)) * 0xff51afd7ed558ccdL;
|
||||
input = (input ^ (input >>> 33)) * 0xc4ceb9fe1a85ec53L;
|
||||
return input ^ (input >>> 33);
|
||||
}
|
||||
@Override
|
||||
protected double sample(double x, double y, double z) {
|
||||
double qWorld = (SQRT_3_OVER_3 * x) - (z / 3D);
|
||||
double rWorld = TWO_OVER_THREE * z;
|
||||
long rootQ = roundQ(qWorld, rWorld);
|
||||
long rootR = roundR(qWorld, rWorld);
|
||||
double centerQ = rootQ;
|
||||
double centerR = rootR;
|
||||
double radius = 1D;
|
||||
double localQ = qWorld - centerQ;
|
||||
double localR = rWorld - centerR;
|
||||
long nodeHash = mix(seed ^ (rootQ * CONST_X) ^ (rootR * CONST_Z));
|
||||
int level = 0;
|
||||
|
||||
private double hashToUnit(long value) {
|
||||
long normalized = mix(value) & Long.MAX_VALUE;
|
||||
return normalized / (double) Long.MAX_VALUE;
|
||||
}
|
||||
while (level < MAX_DEPTH) {
|
||||
int childIndex = pickChildIndex(localQ, localR);
|
||||
if (childIndex < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
private double random01(long nodeHash, int salt) {
|
||||
long mixed = nodeHash ^ (CONST_X * (salt + 1L)) ^ (CONST_Z * (salt + 7L));
|
||||
return hashToUnit(mixed);
|
||||
}
|
||||
double childQ = CHILD_Q[childIndex];
|
||||
double childR = CHILD_R[childIndex];
|
||||
centerQ += childQ * radius;
|
||||
centerR += childR * radius;
|
||||
radius *= ONE_THIRD;
|
||||
localQ = (localQ - childQ) * 3D;
|
||||
localR = (localR - childR) * 3D;
|
||||
nodeHash = mix(nodeHash ^ (CONST_X * (childIndex + 11L)) ^ (CONST_Z * (level + 1L)));
|
||||
level++;
|
||||
|
||||
private long nextNodeHash(long nodeHash, int childIndex, int level) {
|
||||
long mixed = nodeHash ^ (CONST_X * (childIndex + 11L)) ^ (CONST_Z * (level + 1L));
|
||||
return mix(mixed);
|
||||
}
|
||||
|
||||
private long[] roundAxial(double q, double r) {
|
||||
double cubeX = q;
|
||||
double cubeZ = r;
|
||||
double cubeY = -cubeX - cubeZ;
|
||||
long roundedX = Math.round(cubeX);
|
||||
long roundedY = Math.round(cubeY);
|
||||
long roundedZ = Math.round(cubeZ);
|
||||
double xDiff = Math.abs(roundedX - cubeX);
|
||||
double yDiff = Math.abs(roundedY - cubeY);
|
||||
double zDiff = Math.abs(roundedZ - cubeZ);
|
||||
|
||||
if (xDiff > yDiff && xDiff > zDiff) {
|
||||
roundedX = -roundedY - roundedZ;
|
||||
} else if (yDiff > zDiff) {
|
||||
roundedY = -roundedX - roundedZ;
|
||||
} else {
|
||||
roundedZ = -roundedX - roundedY;
|
||||
}
|
||||
|
||||
return new long[]{roundedX, roundedZ};
|
||||
}
|
||||
|
||||
private double hexDistance(double q, double r, double centerQ, double centerR) {
|
||||
double deltaQ = q - centerQ;
|
||||
double deltaR = r - centerR;
|
||||
double deltaY = -deltaQ - deltaR;
|
||||
return Math.max(Math.abs(deltaQ), Math.max(Math.abs(deltaR), Math.abs(deltaY)));
|
||||
}
|
||||
|
||||
private double axialX(double q, double r) {
|
||||
return SQRT_3 * (q + (r * 0.5D));
|
||||
}
|
||||
|
||||
private double axialZ(double r) {
|
||||
return THREE_OVER_TWO * r;
|
||||
}
|
||||
|
||||
private double simplexField(double x, double z, double scale) {
|
||||
if (octaves <= 1) {
|
||||
return heatSimplex.noise(x * scale, z * scale);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double amplitude = 1D;
|
||||
double total = 0D;
|
||||
double max = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
total += heatSimplex.noise((x * scale) * frequency, (z * scale) * frequency) * amplitude;
|
||||
max += amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
if (max == 0D) {
|
||||
return 0.5D;
|
||||
}
|
||||
|
||||
return clip(total / max);
|
||||
}
|
||||
|
||||
private double cellHeat(double centerQ, double centerR, long nodeHash, int level) {
|
||||
double x = axialX(centerQ, centerR);
|
||||
double z = axialZ(centerR);
|
||||
double scale = HEAT_SCALE * (1D + (level * 0.24D));
|
||||
double simplexValue = simplexField(x, z, scale);
|
||||
double randomValue = random01(nodeHash, 31 + level);
|
||||
return clip((simplexValue * 0.82D) + (randomValue * 0.18D));
|
||||
}
|
||||
|
||||
private int rotationForNode(long nodeHash) {
|
||||
int rotation = (int) Math.floor(random01(nodeHash, 3) * 6D);
|
||||
if (rotation < 0) {
|
||||
rotation = 0;
|
||||
}
|
||||
|
||||
if (rotation > 5) {
|
||||
rotation = 5;
|
||||
}
|
||||
|
||||
return rotation;
|
||||
}
|
||||
|
||||
private int parityForNode(long nodeHash) {
|
||||
return random01(nodeHash, 5) >= 0.5D ? 1 : 0;
|
||||
}
|
||||
|
||||
private int ringIndexForDirection(int direction, int rotation) {
|
||||
int ring = direction - rotation;
|
||||
|
||||
while (ring < 0) {
|
||||
ring += 6;
|
||||
}
|
||||
|
||||
while (ring >= 6) {
|
||||
ring -= 6;
|
||||
}
|
||||
|
||||
return ring;
|
||||
}
|
||||
|
||||
private int pickChildIndex(double localQ, double localR, double[] centersQ, double[] centersR) {
|
||||
int bestIndex = -1;
|
||||
double bestDistance = Double.POSITIVE_INFINITY;
|
||||
|
||||
centersQ[0] = 0D;
|
||||
centersR[0] = 0D;
|
||||
double centerDistance = hexDistance(localQ, localR, 0D, 0D) / ONE_THIRD;
|
||||
|
||||
if (centerDistance <= 1D && centerDistance < bestDistance) {
|
||||
bestDistance = centerDistance;
|
||||
bestIndex = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int index = i + 1;
|
||||
double centerQ = CHILD_DIRECTIONS[i][0] * TWO_THIRDS;
|
||||
double centerR = CHILD_DIRECTIONS[i][1] * TWO_THIRDS;
|
||||
centersQ[index] = centerQ;
|
||||
centersR[index] = centerR;
|
||||
double distance = hexDistance(localQ, localR, centerQ, centerR) / ONE_THIRD;
|
||||
|
||||
if (distance <= 1D && distance < bestDistance) {
|
||||
bestDistance = distance;
|
||||
bestIndex = index;
|
||||
if (!shouldContinue(childIndex, nodeHash, level - 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return bestIndex;
|
||||
double centerX = SQRT_3 * (centerQ + (centerR * 0.5D));
|
||||
double centerZ = 1.5D * centerR;
|
||||
double simplexValue = heat.noise(centerX * HEAT_SCALE, y * HEAT_SCALE, centerZ * HEAT_SCALE);
|
||||
return (simplexValue * 0.82D) + (random01(nodeHash, 31 + level) * 0.18D);
|
||||
}
|
||||
|
||||
private boolean shouldContinue(int level, int childIndex, long nodeHash) {
|
||||
private boolean shouldContinue(int childIndex, long nodeHash, int level) {
|
||||
if (level >= MAX_DEPTH - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double gate;
|
||||
|
||||
if (childIndex == 0) {
|
||||
gate = CENTER_CONTINUE;
|
||||
} else {
|
||||
int rotation = rotationForNode(nodeHash);
|
||||
int parity = parityForNode(nodeHash);
|
||||
int ringIndex = ringIndexForDirection(childIndex - 1, rotation);
|
||||
boolean large = (ringIndex % 2) == parity;
|
||||
gate = large ? LARGE_CONTINUE : SMALL_CONTINUE;
|
||||
}
|
||||
|
||||
double randomValue = random01(nodeHash, 97 + level);
|
||||
return randomValue <= gate;
|
||||
}
|
||||
|
||||
private double sample(double x, double z) {
|
||||
HexScratch scratch = SCRATCH.get();
|
||||
double[] centersQ = scratch.centersQ;
|
||||
double[] centersR = scratch.centersR;
|
||||
double qWorld = (SQRT_3_OVER_3 * x) - (z / 3.0);
|
||||
double rWorld = TWO_OVER_THREE * z;
|
||||
long[] rounded = roundAxial(qWorld, rWorld);
|
||||
double centerQ = rounded[0];
|
||||
double centerR = rounded[1];
|
||||
double radius = 0.5D;
|
||||
double localQ = (qWorld - centerQ) / radius;
|
||||
double localR = (rWorld - centerR) / radius;
|
||||
long nodeHash = mix(seed ^ (rounded[0] * CONST_X) ^ (rounded[1] * CONST_Z));
|
||||
double heat = cellHeat(centerQ, centerR, nodeHash, 0);
|
||||
|
||||
for (int level = 0; level < MAX_DEPTH; level++) {
|
||||
int childIndex = pickChildIndex(localQ, localR, centersQ, centersR);
|
||||
|
||||
if (childIndex < 0) {
|
||||
return heat;
|
||||
}
|
||||
|
||||
double childCenterQ = centersQ[childIndex];
|
||||
double childCenterR = centersR[childIndex];
|
||||
centerQ += childCenterQ * radius;
|
||||
centerR += childCenterR * radius;
|
||||
radius *= ONE_THIRD;
|
||||
localQ = (localQ - childCenterQ) / ONE_THIRD;
|
||||
localR = (localR - childCenterR) / ONE_THIRD;
|
||||
nodeHash = nextNodeHash(nodeHash, childIndex, level);
|
||||
heat = cellHeat(centerQ, centerR, nodeHash, level + 1);
|
||||
|
||||
if (!shouldContinue(level, childIndex, nodeHash)) {
|
||||
return heat;
|
||||
double gate = CENTER_CONTINUE;
|
||||
if (childIndex != 0) {
|
||||
int rotation = (int) (random01(nodeHash, 3) * 6D);
|
||||
int parity = random01(nodeHash, 5) >= 0.5D ? 1 : 0;
|
||||
int direction = childIndex - 1 - rotation;
|
||||
if (direction < 0) {
|
||||
direction += 6;
|
||||
}
|
||||
gate = (direction % 2) == parity ? LARGE_CONTINUE : SMALL_CONTINUE;
|
||||
}
|
||||
|
||||
return heat;
|
||||
return random01(nodeHash, 97 + level) <= gate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
return sample(x, 0D);
|
||||
private double random01(long nodeHash, int salt) {
|
||||
long mixed = nodeHash ^ (CONST_X * (salt + 1L)) ^ (CONST_Z * (salt + 7L));
|
||||
return (mix(mixed) >>> 11) * 0x1.0p-53;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
return sample(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
if (z == 0D) {
|
||||
return sample(x, y);
|
||||
}
|
||||
|
||||
double a = sample(x, z);
|
||||
double b = sample(y, x);
|
||||
double c = sample(z, y);
|
||||
return (a + b + c) / 3D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOctaves(int o) {
|
||||
this.octaves = Math.max(1, o);
|
||||
}
|
||||
|
||||
private static final class HexScratch {
|
||||
private final double[] centersQ = new double[7];
|
||||
private final double[] centersR = new double[7];
|
||||
}
|
||||
}
|
||||
@@ -2,259 +2,77 @@ package art.arcane.iris.util.project.noise;
|
||||
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
|
||||
public class HexRandomSizeNoise implements NoiseGenerator, OctaveNoise {
|
||||
private static final double SQRT_3_OVER_3 = Math.sqrt(3.0) / 3.0;
|
||||
private static final double TWO_OVER_THREE = 2.0 / 3.0;
|
||||
private static final double SQRT_3 = Math.sqrt(3.0);
|
||||
private static final double THREE_OVER_TWO = 1.5D;
|
||||
private static final double ONE_THIRD = 1D / 3D;
|
||||
private static final double TWO_THIRDS = 2D / 3D;
|
||||
public class HexRandomSizeNoise extends HexagonalNoise implements OctaveNoise {
|
||||
private static final int MAX_DEPTH = 8;
|
||||
private static final double HEAT_SCALE = 0.24D;
|
||||
private static final double STRUCTURE_SCALE = 0.36D;
|
||||
private static final double HEAT_SCALE = 18D;
|
||||
private static final double STRUCTURE_SCALE = 36D;
|
||||
private static final double SUBDIVIDE_BASE_THRESHOLD = 0.22D;
|
||||
private static final double SUBDIVIDE_LEVEL_STEP = 0.11D;
|
||||
private static final long CONST_X = 0x9E3779B97F4A7C15L;
|
||||
private static final long CONST_Z = 0xC2B2AE3D27D4EB4FL;
|
||||
private static final long[][] CHILD_DIRECTIONS = new long[][]{
|
||||
{1L, 0L},
|
||||
{1L, -1L},
|
||||
{0L, -1L},
|
||||
{-1L, 0L},
|
||||
{-1L, 1L},
|
||||
{0L, 1L}
|
||||
};
|
||||
private static final ThreadLocal<HexScratch> SCRATCH = ThreadLocal.withInitial(HexScratch::new);
|
||||
private final long seed;
|
||||
private final SimplexNoise heatSimplex;
|
||||
private final SimplexNoise structureSimplex;
|
||||
private int octaves;
|
||||
private final SimplexNoise heat;
|
||||
private final SimplexNoise structure;
|
||||
|
||||
public HexRandomSizeNoise(long seed) {
|
||||
RNG rng = new RNG(seed);
|
||||
this.seed = rng.lmax();
|
||||
this.heatSimplex = new SimplexNoise(rng.nextParallelRNG(221L).lmax());
|
||||
this.structureSimplex = new SimplexNoise(rng.nextParallelRNG(442L).lmax());
|
||||
this.octaves = 1;
|
||||
this.heat = new SimplexNoise(rng.nextParallelRNG(221L).lmax());
|
||||
this.structure = new SimplexNoise(rng.nextParallelRNG(442L).lmax());
|
||||
}
|
||||
|
||||
private double clip(double value) {
|
||||
if (value < 0D) {
|
||||
return 0D;
|
||||
@Override
|
||||
public void setOctaves(int octaves) {
|
||||
heat.setOctaves(octaves);
|
||||
structure.setOctaves(octaves);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected double sample(double x, double y, double z) {
|
||||
double qWorld = (SQRT_3_OVER_3 * x) - (z / 3D);
|
||||
double rWorld = TWO_OVER_THREE * z;
|
||||
long rootQ = roundQ(qWorld, rWorld);
|
||||
long rootR = roundR(qWorld, rWorld);
|
||||
double centerQ = rootQ;
|
||||
double centerR = rootR;
|
||||
double radius = 1D;
|
||||
double localQ = qWorld - centerQ;
|
||||
double localR = rWorld - centerR;
|
||||
long nodeHash = mix(seed ^ (rootQ * CONST_X) ^ (rootR * CONST_Z));
|
||||
int level = 0;
|
||||
|
||||
while (level < MAX_DEPTH - 1 && shouldSubdivide(centerQ, centerR, nodeHash, level)) {
|
||||
int childIndex = pickChildIndex(localQ, localR);
|
||||
if (childIndex < 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
double childQ = CHILD_Q[childIndex];
|
||||
double childR = CHILD_R[childIndex];
|
||||
centerQ += childQ * radius;
|
||||
centerR += childR * radius;
|
||||
radius *= ONE_THIRD;
|
||||
localQ = (localQ - childQ) * 3D;
|
||||
localR = (localR - childR) * 3D;
|
||||
nodeHash = mix(nodeHash ^ (CONST_Z * (childIndex + 1L)) ^ (CONST_X * (level + 1L)));
|
||||
level++;
|
||||
}
|
||||
|
||||
if (value > 1D) {
|
||||
return 1D;
|
||||
}
|
||||
|
||||
return value;
|
||||
double centerX = SQRT_3 * (centerQ + (centerR * 0.5D));
|
||||
double centerZ = 1.5D * centerR;
|
||||
double simplexValue = heat.noise(centerX * HEAT_SCALE, y * HEAT_SCALE, centerZ * HEAT_SCALE);
|
||||
return (simplexValue * 0.74D) + (random01(nodeHash, 11 + level) * 0.26D);
|
||||
}
|
||||
|
||||
private long mix(long input) {
|
||||
input = (input ^ (input >>> 33)) * 0xff51afd7ed558ccdL;
|
||||
input = (input ^ (input >>> 33)) * 0xc4ceb9fe1a85ec53L;
|
||||
return input ^ (input >>> 33);
|
||||
}
|
||||
|
||||
private double hashToUnit(long value) {
|
||||
long normalized = mix(value) & Long.MAX_VALUE;
|
||||
return normalized / (double) Long.MAX_VALUE;
|
||||
private boolean shouldSubdivide(double centerQ, double centerR, long nodeHash, int level) {
|
||||
double centerX = SQRT_3 * (centerQ + (centerR * 0.5D));
|
||||
double centerZ = 1.5D * centerR;
|
||||
double simplexValue = structure.noise(centerX * STRUCTURE_SCALE, centerZ * STRUCTURE_SCALE);
|
||||
double score = (simplexValue * 0.68D) + (random01(nodeHash, 71 + level) * 0.32D);
|
||||
return score > SUBDIVIDE_BASE_THRESHOLD + (level * SUBDIVIDE_LEVEL_STEP);
|
||||
}
|
||||
|
||||
private double random01(long nodeHash, int salt) {
|
||||
long mixed = nodeHash ^ (CONST_X * (salt + 1L)) ^ (CONST_Z * (salt + 31L));
|
||||
return hashToUnit(mixed);
|
||||
return (mix(mixed) >>> 11) * 0x1.0p-53;
|
||||
}
|
||||
|
||||
private long nextNodeHash(long nodeHash, int childIndex, int level) {
|
||||
long mixed = nodeHash ^ (CONST_Z * (childIndex + 1L)) ^ (CONST_X * (level + 1L));
|
||||
return mix(mixed);
|
||||
}
|
||||
|
||||
private long[] roundAxial(double q, double r) {
|
||||
double cubeX = q;
|
||||
double cubeZ = r;
|
||||
double cubeY = -cubeX - cubeZ;
|
||||
long roundedX = Math.round(cubeX);
|
||||
long roundedY = Math.round(cubeY);
|
||||
long roundedZ = Math.round(cubeZ);
|
||||
double xDiff = Math.abs(roundedX - cubeX);
|
||||
double yDiff = Math.abs(roundedY - cubeY);
|
||||
double zDiff = Math.abs(roundedZ - cubeZ);
|
||||
|
||||
if (xDiff > yDiff && xDiff > zDiff) {
|
||||
roundedX = -roundedY - roundedZ;
|
||||
} else if (yDiff > zDiff) {
|
||||
roundedY = -roundedX - roundedZ;
|
||||
} else {
|
||||
roundedZ = -roundedX - roundedY;
|
||||
}
|
||||
|
||||
return new long[]{roundedX, roundedZ};
|
||||
}
|
||||
|
||||
private double hexDistance(double q, double r, double centerQ, double centerR) {
|
||||
double deltaQ = q - centerQ;
|
||||
double deltaR = r - centerR;
|
||||
double deltaY = -deltaQ - deltaR;
|
||||
return Math.max(Math.abs(deltaQ), Math.max(Math.abs(deltaR), Math.abs(deltaY)));
|
||||
}
|
||||
|
||||
private double axialX(double q, double r) {
|
||||
return SQRT_3 * (q + (r * 0.5D));
|
||||
}
|
||||
|
||||
private double axialZ(double r) {
|
||||
return THREE_OVER_TWO * r;
|
||||
}
|
||||
|
||||
private double simplexField(SimplexNoise simplex, double x, double z, double scale) {
|
||||
if (octaves <= 1) {
|
||||
return simplex.noise(x * scale, z * scale);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double amplitude = 1D;
|
||||
double total = 0D;
|
||||
double max = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
total += simplex.noise((x * scale) * frequency, (z * scale) * frequency) * amplitude;
|
||||
max += amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
if (max == 0D) {
|
||||
return 0.5D;
|
||||
}
|
||||
|
||||
return clip(total / max);
|
||||
}
|
||||
|
||||
private double cellHeat(double centerQ, double centerR, long nodeHash, int level) {
|
||||
double x = axialX(centerQ, centerR);
|
||||
double z = axialZ(centerR);
|
||||
double scale = HEAT_SCALE * (1D + (level * 0.2D));
|
||||
double simplexValue = simplexField(heatSimplex, x, z, scale);
|
||||
double randomValue = random01(nodeHash, 11 + level);
|
||||
return clip((simplexValue * 0.74D) + (randomValue * 0.26D));
|
||||
}
|
||||
|
||||
private boolean shouldSubdivide(double centerQ, double centerR, long nodeHash, int level) {
|
||||
if (level >= MAX_DEPTH - 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
double x = axialX(centerQ, centerR);
|
||||
double z = axialZ(centerR);
|
||||
double scale = STRUCTURE_SCALE * (1D + (level * 0.31D));
|
||||
double simplexValue = simplexField(structureSimplex, x, z, scale);
|
||||
double randomValue = random01(nodeHash, 71 + level);
|
||||
double score = clip((simplexValue * 0.68D) + (randomValue * 0.32D));
|
||||
double threshold = SUBDIVIDE_BASE_THRESHOLD + (level * SUBDIVIDE_LEVEL_STEP);
|
||||
return score > threshold;
|
||||
}
|
||||
|
||||
private int pickChildIndex(double localQ, double localR, double[] centersQ, double[] centersR) {
|
||||
int bestIndex = -1;
|
||||
double bestDistance = Double.POSITIVE_INFINITY;
|
||||
|
||||
centersQ[0] = 0D;
|
||||
centersR[0] = 0D;
|
||||
double centerDistance = hexDistance(localQ, localR, 0D, 0D) / ONE_THIRD;
|
||||
|
||||
if (centerDistance <= 1D && centerDistance < bestDistance) {
|
||||
bestDistance = centerDistance;
|
||||
bestIndex = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
int index = i + 1;
|
||||
double centerQ = CHILD_DIRECTIONS[i][0] * TWO_THIRDS;
|
||||
double centerR = CHILD_DIRECTIONS[i][1] * TWO_THIRDS;
|
||||
centersQ[index] = centerQ;
|
||||
centersR[index] = centerR;
|
||||
double distance = hexDistance(localQ, localR, centerQ, centerR) / ONE_THIRD;
|
||||
|
||||
if (distance <= 1D && distance < bestDistance) {
|
||||
bestDistance = distance;
|
||||
bestIndex = index;
|
||||
}
|
||||
}
|
||||
|
||||
return bestIndex;
|
||||
}
|
||||
|
||||
private double sample(double x, double z) {
|
||||
HexScratch scratch = SCRATCH.get();
|
||||
double[] centersQ = scratch.centersQ;
|
||||
double[] centersR = scratch.centersR;
|
||||
double qWorld = (SQRT_3_OVER_3 * x) - (z / 3.0);
|
||||
double rWorld = TWO_OVER_THREE * z;
|
||||
long[] rounded = roundAxial(qWorld, rWorld);
|
||||
double centerQ = rounded[0];
|
||||
double centerR = rounded[1];
|
||||
double radius = 0.5D;
|
||||
double localQ = (qWorld - centerQ) / radius;
|
||||
double localR = (rWorld - centerR) / radius;
|
||||
long nodeHash = mix(seed ^ (rounded[0] * CONST_X) ^ (rounded[1] * CONST_Z));
|
||||
double heat = cellHeat(centerQ, centerR, nodeHash, 0);
|
||||
|
||||
for (int level = 0; level < MAX_DEPTH; level++) {
|
||||
if (!shouldSubdivide(centerQ, centerR, nodeHash, level)) {
|
||||
return heat;
|
||||
}
|
||||
|
||||
int childIndex = pickChildIndex(localQ, localR, centersQ, centersR);
|
||||
|
||||
if (childIndex < 0) {
|
||||
return heat;
|
||||
}
|
||||
|
||||
double childCenterQ = centersQ[childIndex];
|
||||
double childCenterR = centersR[childIndex];
|
||||
centerQ += childCenterQ * radius;
|
||||
centerR += childCenterR * radius;
|
||||
radius *= ONE_THIRD;
|
||||
localQ = (localQ - childCenterQ) / ONE_THIRD;
|
||||
localR = (localR - childCenterR) / ONE_THIRD;
|
||||
nodeHash = nextNodeHash(nodeHash, childIndex, level);
|
||||
heat = cellHeat(centerQ, centerR, nodeHash, level + 1);
|
||||
}
|
||||
|
||||
return heat;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
return sample(x, 0D);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
return sample(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
if (z == 0D) {
|
||||
return sample(x, y);
|
||||
}
|
||||
|
||||
double a = sample(x, z);
|
||||
double b = sample(y, x);
|
||||
double c = sample(z, y);
|
||||
return (a + b + c) / 3D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOctaves(int o) {
|
||||
this.octaves = Math.max(1, o);
|
||||
}
|
||||
|
||||
private static final class HexScratch {
|
||||
private final double[] centersQ = new double[7];
|
||||
private final double[] centersR = new double[7];
|
||||
}
|
||||
}
|
||||
@@ -2,124 +2,27 @@ package art.arcane.iris.util.project.noise;
|
||||
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
|
||||
public class HexSimplexNoise implements NoiseGenerator, OctaveNoise {
|
||||
private static final double SQRT_3_OVER_3 = Math.sqrt(3.0) / 3.0;
|
||||
private static final double TWO_OVER_THREE = 2.0 / 3.0;
|
||||
private static final double SQRT_3 = Math.sqrt(3.0);
|
||||
private static final double THREE_OVER_TWO = 1.5D;
|
||||
private static final double CELL_HEAT_SCALE = 2.7D;
|
||||
private final SimplexNoise cellHeatSimplex;
|
||||
private int octaves;
|
||||
public class HexSimplexNoise extends HexagonalNoise implements OctaveNoise {
|
||||
private static final double HEAT_SCALE = 18D;
|
||||
private final SimplexNoise heat;
|
||||
|
||||
public HexSimplexNoise(long seed) {
|
||||
RNG rng = new RNG(seed);
|
||||
this.cellHeatSimplex = new SimplexNoise(rng.nextParallelRNG(811L).lmax());
|
||||
this.octaves = 1;
|
||||
this.heat = new SimplexNoise(new RNG(seed).nextParallelRNG(811L).lmax());
|
||||
}
|
||||
|
||||
private double clip(double value) {
|
||||
if (value < 0D) {
|
||||
return 0D;
|
||||
}
|
||||
|
||||
if (value > 1D) {
|
||||
return 1D;
|
||||
}
|
||||
|
||||
return value;
|
||||
@Override
|
||||
public void setOctaves(int octaves) {
|
||||
heat.setOctaves(octaves);
|
||||
}
|
||||
|
||||
private long[] roundAxial(double q, double r) {
|
||||
double cubeX = q;
|
||||
double cubeZ = r;
|
||||
double cubeY = -cubeX - cubeZ;
|
||||
long roundedX = Math.round(cubeX);
|
||||
long roundedY = Math.round(cubeY);
|
||||
long roundedZ = Math.round(cubeZ);
|
||||
double xDiff = Math.abs(roundedX - cubeX);
|
||||
double yDiff = Math.abs(roundedY - cubeY);
|
||||
double zDiff = Math.abs(roundedZ - cubeZ);
|
||||
|
||||
if (xDiff > yDiff && xDiff > zDiff) {
|
||||
roundedX = -roundedY - roundedZ;
|
||||
} else if (yDiff > zDiff) {
|
||||
roundedY = -roundedX - roundedZ;
|
||||
} else {
|
||||
roundedZ = -roundedX - roundedY;
|
||||
}
|
||||
|
||||
return new long[]{roundedX, roundedZ};
|
||||
}
|
||||
|
||||
private double axialX(long q, long r) {
|
||||
return SQRT_3 * (q + (r * 0.5D));
|
||||
}
|
||||
|
||||
private double axialZ(long r) {
|
||||
return THREE_OVER_TWO * r;
|
||||
}
|
||||
|
||||
private double cellHeat(long q, long r, double frequency) {
|
||||
double x = axialX(q, r);
|
||||
double z = axialZ(r);
|
||||
return cellHeatSimplex.noise((x * CELL_HEAT_SCALE) * frequency, (z * CELL_HEAT_SCALE) * frequency);
|
||||
}
|
||||
|
||||
private double sampleCell(long q, long r) {
|
||||
if (octaves <= 1) {
|
||||
return cellHeat(q, r, 1D);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double amplitude = 1D;
|
||||
double total = 0D;
|
||||
double max = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
total += cellHeat(q, r, frequency) * amplitude;
|
||||
max += amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
if (max == 0D) {
|
||||
return 0.5D;
|
||||
}
|
||||
|
||||
return clip(total / max);
|
||||
}
|
||||
|
||||
private double sample(double x, double z) {
|
||||
double q = (SQRT_3_OVER_3 * x) - (z / 3.0);
|
||||
@Override
|
||||
protected double sample(double x, double y, double z) {
|
||||
double q = (SQRT_3_OVER_3 * x) - (z / 3D);
|
||||
double r = TWO_OVER_THREE * z;
|
||||
long[] rounded = roundAxial(q, r);
|
||||
return sampleCell(rounded[0], rounded[1]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
return sample(x, 0D);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
return sample(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
if (z == 0D) {
|
||||
return sample(x, y);
|
||||
}
|
||||
|
||||
double a = sample(x, z);
|
||||
double b = sample(y, x);
|
||||
double c = sample(z, y);
|
||||
return (a + b + c) / 3D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOctaves(int o) {
|
||||
this.octaves = Math.max(1, o);
|
||||
long centerQ = roundQ(q, r);
|
||||
long centerR = roundR(q, r);
|
||||
double centerX = SQRT_3 * (centerQ + (centerR * 0.5D));
|
||||
double centerZ = 1.5D * centerR;
|
||||
return heat.noise(centerX * HEAT_SCALE, y * HEAT_SCALE, centerZ * HEAT_SCALE);
|
||||
}
|
||||
}
|
||||
@@ -2,82 +2,27 @@ package art.arcane.iris.util.project.noise;
|
||||
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
|
||||
public class HexagonNoise implements NoiseGenerator {
|
||||
private static final double SQRT_3_OVER_3 = Math.sqrt(3.0) / 3.0;
|
||||
private static final double TWO_OVER_THREE = 2.0 / 3.0;
|
||||
private static final long CONST_X = 0x9E3779B97F4A7C15L;
|
||||
private static final long CONST_Z = 0xC2B2AE3D27D4EB4FL;
|
||||
private final long seed;
|
||||
public class HexagonNoise extends HexagonalNoise implements OctaveNoise {
|
||||
private static final double HEAT_SCALE = 18D;
|
||||
private final SimplexNoise heat;
|
||||
|
||||
public HexagonNoise(long seed) {
|
||||
this.seed = new RNG(seed).lmax();
|
||||
this.heat = new SimplexNoise(new RNG(seed).lmax());
|
||||
}
|
||||
|
||||
private long mix(long input) {
|
||||
input = (input ^ (input >>> 33)) * 0xff51afd7ed558ccdL;
|
||||
input = (input ^ (input >>> 33)) * 0xc4ceb9fe1a85ec53L;
|
||||
return input ^ (input >>> 33);
|
||||
@Override
|
||||
public void setOctaves(int octaves) {
|
||||
heat.setOctaves(octaves);
|
||||
}
|
||||
|
||||
private long hash(long q, long r) {
|
||||
long hash = seed;
|
||||
hash ^= mix(q + CONST_X);
|
||||
hash ^= mix(r + CONST_Z);
|
||||
return mix(hash);
|
||||
}
|
||||
|
||||
private long[] roundAxial(double q, double r) {
|
||||
double cubeX = q;
|
||||
double cubeZ = r;
|
||||
double cubeY = -cubeX - cubeZ;
|
||||
|
||||
long rx = Math.round(cubeX);
|
||||
long ry = Math.round(cubeY);
|
||||
long rz = Math.round(cubeZ);
|
||||
|
||||
double xDiff = Math.abs(rx - cubeX);
|
||||
double yDiff = Math.abs(ry - cubeY);
|
||||
double zDiff = Math.abs(rz - cubeZ);
|
||||
|
||||
if (xDiff > yDiff && xDiff > zDiff) {
|
||||
rx = -ry - rz;
|
||||
} else if (yDiff > zDiff) {
|
||||
ry = -rx - rz;
|
||||
} else {
|
||||
rz = -rx - ry;
|
||||
}
|
||||
|
||||
return new long[]{rx, rz};
|
||||
}
|
||||
|
||||
private double sampleCell(double x, double z) {
|
||||
double q = (SQRT_3_OVER_3 * x) - (z / 3.0);
|
||||
@Override
|
||||
protected double sample(double x, double y, double z) {
|
||||
double q = (SQRT_3_OVER_3 * x) - (z / 3D);
|
||||
double r = TWO_OVER_THREE * z;
|
||||
long[] axial = roundAxial(q, r);
|
||||
long hashed = hash(axial[0], axial[1]);
|
||||
long normalized = hashed & Long.MAX_VALUE;
|
||||
return normalized / (double) Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
return sampleCell(x, 0D);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
return sampleCell(x, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
if (z == 0D) {
|
||||
return sampleCell(x, y);
|
||||
}
|
||||
|
||||
double a = sampleCell(x, z);
|
||||
double b = sampleCell(y, x);
|
||||
double c = sampleCell(z, y);
|
||||
return (a + b + c) / 3D;
|
||||
long centerQ = roundQ(q, r);
|
||||
long centerR = roundR(q, r);
|
||||
double centerX = SQRT_3 * (centerQ + (centerR * 0.5D));
|
||||
double centerZ = 1.5D * centerR;
|
||||
return heat.noise(centerX * HEAT_SCALE, y * HEAT_SCALE, centerZ * HEAT_SCALE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package art.arcane.iris.util.project.noise;
|
||||
|
||||
abstract class HexagonalNoise implements NoiseGenerator {
|
||||
protected static final double SQRT_3 = Math.sqrt(3D);
|
||||
protected static final double SQRT_3_OVER_3 = SQRT_3 / 3D;
|
||||
protected static final double TWO_OVER_THREE = 2D / 3D;
|
||||
protected static final double ONE_THIRD = 1D / 3D;
|
||||
protected static final double[] CHILD_Q = {0D, 4D / 9D, 2D / 9D, -2D / 9D, -4D / 9D, -2D / 9D, 2D / 9D};
|
||||
protected static final double[] CHILD_R = {0D, -2D / 9D, 2D / 9D, 4D / 9D, 2D / 9D, -2D / 9D, -4D / 9D};
|
||||
protected static final long CONST_X = 0x9E3779B97F4A7C15L;
|
||||
protected static final long CONST_Z = 0xC2B2AE3D27D4EB4FL;
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
return sample(x, 0D, 0D);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
return sample(x, 0D, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
return sample(x, y, z);
|
||||
}
|
||||
|
||||
protected abstract double sample(double x, double y, double z);
|
||||
|
||||
protected static long roundQ(double q, double r) {
|
||||
double cubeY = -q - r;
|
||||
long roundedQ = Math.round(q);
|
||||
long roundedR = Math.round(r);
|
||||
long roundedY = Math.round(cubeY);
|
||||
double qDiff = Math.abs(roundedQ - q);
|
||||
double rDiff = Math.abs(roundedR - r);
|
||||
double yDiff = Math.abs(roundedY - cubeY);
|
||||
return qDiff > yDiff && qDiff > rDiff ? -roundedY - roundedR : roundedQ;
|
||||
}
|
||||
|
||||
protected static long roundR(double q, double r) {
|
||||
double cubeY = -q - r;
|
||||
long roundedQ = Math.round(q);
|
||||
long roundedR = Math.round(r);
|
||||
long roundedY = Math.round(cubeY);
|
||||
double qDiff = Math.abs(roundedQ - q);
|
||||
double rDiff = Math.abs(roundedR - r);
|
||||
double yDiff = Math.abs(roundedY - cubeY);
|
||||
return !(qDiff > yDiff && qDiff > rDiff) && yDiff <= rDiff ? -roundedQ - roundedY : roundedR;
|
||||
}
|
||||
|
||||
protected static long mix(long input) {
|
||||
input = (input ^ (input >>> 33)) * 0xff51afd7ed558ccdL;
|
||||
input = (input ^ (input >>> 33)) * 0xc4ceb9fe1a85ec53L;
|
||||
return input ^ (input >>> 33);
|
||||
}
|
||||
|
||||
protected static int pickChildIndex(double localQ, double localR) {
|
||||
for (int index = 0; index < CHILD_Q.length; index++) {
|
||||
double deltaQ = localQ - CHILD_Q[index];
|
||||
double deltaR = localR - CHILD_R[index];
|
||||
double distance = Math.max(Math.abs((2D * deltaQ) + deltaR),
|
||||
Math.max(Math.abs(deltaQ + (2D * deltaR)), Math.abs(deltaQ - deltaR)));
|
||||
if (distance <= ONE_THIRD) {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -21,14 +21,16 @@ package art.arcane.iris.util.project.noise;
|
||||
import art.arcane.volmlib.util.function.NoiseProvider;
|
||||
import art.arcane.iris.util.project.interpolation.InterpolationMethod;
|
||||
import art.arcane.iris.util.project.interpolation.IrisInterpolation;
|
||||
public class InterpolatedNoise implements NoiseGenerator {
|
||||
public class InterpolatedNoise implements NoiseGenerator, OctaveNoise {
|
||||
private final InterpolationMethod method;
|
||||
private final NoiseGenerator generator;
|
||||
private final NoiseProvider p;
|
||||
|
||||
public InterpolatedNoise(long seed, NoiseType type, InterpolationMethod method) {
|
||||
this.method = method;
|
||||
NoiseGenerator g = type.create(seed);
|
||||
p = g::noise;
|
||||
generator = type.create(seed);
|
||||
double coordinateScale = type.getCoordinateScale();
|
||||
p = (x, z) -> generator.noise(x * coordinateScale, z * coordinateScale);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -38,15 +40,18 @@ public class InterpolatedNoise implements NoiseGenerator {
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
return IrisInterpolation.getNoise(method, (int) x, (int) z, 32, p);
|
||||
return Math.max(0D, Math.min(1D, IrisInterpolation.getNoise(method, x, z, 32, p)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
if (z == 0) {
|
||||
return noise(x, y);
|
||||
}
|
||||
return noise(x, z);
|
||||
}
|
||||
|
||||
return IrisInterpolation.getNoise(method, (int) x, (int) z, 32, p);
|
||||
@Override
|
||||
public void setOctaves(int octaves) {
|
||||
if (generator instanceof OctaveNoise octaveNoise) {
|
||||
octaveNoise.setOctaves(octaves);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,79 +20,89 @@ package art.arcane.iris.util.project.noise;
|
||||
|
||||
import art.arcane.iris.util.project.interpolation.InterpolationMethod;
|
||||
public enum NoiseType {
|
||||
WHITE(WhiteNoise::new),
|
||||
WHITE_BILINEAR((s) -> new InterpolatedNoise(s, WHITE, InterpolationMethod.BILINEAR)),
|
||||
WHITE_BICUBIC((s) -> new InterpolatedNoise(s, WHITE, InterpolationMethod.BICUBIC)),
|
||||
WHITE_HERMITE((s) -> new InterpolatedNoise(s, WHITE, InterpolationMethod.HERMITE)),
|
||||
WHITE(WhiteNoise::new, 1D),
|
||||
WHITE_BILINEAR((s) -> new InterpolatedNoise(s, WHITE, InterpolationMethod.BILINEAR), 1D),
|
||||
WHITE_BICUBIC((s) -> new InterpolatedNoise(s, WHITE, InterpolationMethod.BICUBIC), 1D),
|
||||
WHITE_HERMITE((s) -> new InterpolatedNoise(s, WHITE, InterpolationMethod.HERMITE), 1D),
|
||||
SIMPLEX(SimplexNoise::new),
|
||||
PERLIN(seed -> new PerlinNoise(seed).hermite()),
|
||||
PERLIN(PerlinNoise::new),
|
||||
FRACTAL_BILLOW_SIMPLEX(FractalBillowSimplexNoise::new),
|
||||
FRACTAL_BILLOW_PERLIN(FractalBillowPerlinNoise::new),
|
||||
FRACTAL_FBM_SIMPLEX(FractalFBMSimplexNoise::new),
|
||||
FRACTAL_RIGID_MULTI_SIMPLEX(FractalRigidMultiSimplexNoise::new),
|
||||
FLAT(FlatNoise::new),
|
||||
FLAT(FlatNoise::new, 1D),
|
||||
CELLULAR(CellularNoise::new),
|
||||
CELLULAR_BILINEAR((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR)),
|
||||
CELLULAR_BILINEAR_STARCAST_3((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR_STARCAST_3)),
|
||||
CELLULAR_BILINEAR_STARCAST_6((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR_STARCAST_6)),
|
||||
CELLULAR_BILINEAR_STARCAST_9((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR_STARCAST_9)),
|
||||
CELLULAR_BILINEAR_STARCAST_12((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR_STARCAST_12)),
|
||||
CELLULAR_BICUBIC((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BICUBIC)),
|
||||
CELLULAR_HERMITE((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE)),
|
||||
CELLULAR_STARCAST_3((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.STARCAST_3)),
|
||||
CELLULAR_STARCAST_6((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.STARCAST_6)),
|
||||
CELLULAR_STARCAST_9((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.STARCAST_9)),
|
||||
CELLULAR_STARCAST_12((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.STARCAST_12)),
|
||||
CELLULAR_HERMITE_STARCAST_3((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE_STARCAST_3)),
|
||||
CELLULAR_HERMITE_STARCAST_6((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE_STARCAST_6)),
|
||||
CELLULAR_HERMITE_STARCAST_9((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE_STARCAST_9)),
|
||||
CELLULAR_HERMITE_STARCAST_12((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE_STARCAST_12)),
|
||||
CELLULAR_BILINEAR((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR), 1D),
|
||||
CELLULAR_BILINEAR_STARCAST_3((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR_STARCAST_3), 1D),
|
||||
CELLULAR_BILINEAR_STARCAST_6((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR_STARCAST_6), 1D),
|
||||
CELLULAR_BILINEAR_STARCAST_9((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR_STARCAST_9), 1D),
|
||||
CELLULAR_BILINEAR_STARCAST_12((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BILINEAR_STARCAST_12), 1D),
|
||||
CELLULAR_BICUBIC((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.BICUBIC), 1D),
|
||||
CELLULAR_HERMITE((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE), 1D),
|
||||
CELLULAR_STARCAST_3((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.STARCAST_3), 1D),
|
||||
CELLULAR_STARCAST_6((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.STARCAST_6), 1D),
|
||||
CELLULAR_STARCAST_9((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.STARCAST_9), 1D),
|
||||
CELLULAR_STARCAST_12((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.STARCAST_12), 1D),
|
||||
CELLULAR_HERMITE_STARCAST_3((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE_STARCAST_3), 1D),
|
||||
CELLULAR_HERMITE_STARCAST_6((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE_STARCAST_6), 1D),
|
||||
CELLULAR_HERMITE_STARCAST_9((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE_STARCAST_9), 1D),
|
||||
CELLULAR_HERMITE_STARCAST_12((s) -> new InterpolatedNoise(s, CELLULAR, InterpolationMethod.HERMITE_STARCAST_12), 1D),
|
||||
GLOB(GlobNoise::new),
|
||||
CUBIC(CubicNoise::new),
|
||||
FRACTAL_CUBIC(FractalCubicNoise::new),
|
||||
CELLULAR_HEIGHT(CellHeightNoise::new),
|
||||
CLOVER(CloverNoise::new),
|
||||
CLOVER_BILINEAR((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR)),
|
||||
CLOVER_BILINEAR_STARCAST_3((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR_STARCAST_3)),
|
||||
CLOVER_BILINEAR_STARCAST_6((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR_STARCAST_6)),
|
||||
CLOVER_BILINEAR_STARCAST_9((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR_STARCAST_9)),
|
||||
CLOVER_BILINEAR_STARCAST_12((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR_STARCAST_12)),
|
||||
CLOVER_BICUBIC((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BICUBIC)),
|
||||
CLOVER_HERMITE((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE)),
|
||||
CLOVER_STARCAST_3((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.STARCAST_3)),
|
||||
CLOVER_STARCAST_6((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.STARCAST_6)),
|
||||
CLOVER_STARCAST_9((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.STARCAST_9)),
|
||||
CLOVER_STARCAST_12((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.STARCAST_12)),
|
||||
CLOVER_HERMITE_STARCAST_3((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE_STARCAST_3)),
|
||||
CLOVER_HERMITE_STARCAST_6((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE_STARCAST_6)),
|
||||
CLOVER_HERMITE_STARCAST_9((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE_STARCAST_9)),
|
||||
CLOVER_HERMITE_STARCAST_12((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE_STARCAST_12)),
|
||||
HEXAGON(HexagonNoise::new),
|
||||
HEXAGON_BILINEAR((s) -> new InterpolatedNoise(s, HEXAGON, InterpolationMethod.BILINEAR)),
|
||||
HEXAGON_BICUBIC((s) -> new InterpolatedNoise(s, HEXAGON, InterpolationMethod.BICUBIC)),
|
||||
HEXAGON_HERMITE((s) -> new InterpolatedNoise(s, HEXAGON, InterpolationMethod.HERMITE)),
|
||||
HEX_JAMES(HexJamesNoise::new),
|
||||
HEX_JAMES_BILINEAR((s) -> new InterpolatedNoise(s, HEX_JAMES, InterpolationMethod.BILINEAR)),
|
||||
HEX_JAMES_BICUBIC((s) -> new InterpolatedNoise(s, HEX_JAMES, InterpolationMethod.BICUBIC)),
|
||||
HEX_JAMES_HERMITE((s) -> new InterpolatedNoise(s, HEX_JAMES, InterpolationMethod.HERMITE)),
|
||||
HEX_SIMPLEX(HexSimplexNoise::new),
|
||||
HEX_SIMPLEX_BILINEAR((s) -> new InterpolatedNoise(s, HEX_SIMPLEX, InterpolationMethod.BILINEAR)),
|
||||
HEX_SIMPLEX_BICUBIC((s) -> new InterpolatedNoise(s, HEX_SIMPLEX, InterpolationMethod.BICUBIC)),
|
||||
HEX_SIMPLEX_HERMITE((s) -> new InterpolatedNoise(s, HEX_SIMPLEX, InterpolationMethod.HERMITE)),
|
||||
HEX_RANDOM_SIZE(HexRandomSizeNoise::new),
|
||||
HEX_RANDOM_SIZE_BILINEAR((s) -> new InterpolatedNoise(s, HEX_RANDOM_SIZE, InterpolationMethod.BILINEAR)),
|
||||
HEX_RANDOM_SIZE_BICUBIC((s) -> new InterpolatedNoise(s, HEX_RANDOM_SIZE, InterpolationMethod.BICUBIC)),
|
||||
HEX_RANDOM_SIZE_HERMITE((s) -> new InterpolatedNoise(s, HEX_RANDOM_SIZE, InterpolationMethod.HERMITE)),
|
||||
SIERPINSKI_TRIANGLE(SierpinskiTriangleNoise::new),
|
||||
SIERPINSKI_TRIANGLE_BILINEAR((s) -> new InterpolatedNoise(s, SIERPINSKI_TRIANGLE, InterpolationMethod.BILINEAR)),
|
||||
SIERPINSKI_TRIANGLE_BICUBIC((s) -> new InterpolatedNoise(s, SIERPINSKI_TRIANGLE, InterpolationMethod.BICUBIC)),
|
||||
SIERPINSKI_TRIANGLE_HERMITE((s) -> new InterpolatedNoise(s, SIERPINSKI_TRIANGLE, InterpolationMethod.HERMITE)),
|
||||
CLOVER(CloverNoise::new, 1D / 64D),
|
||||
CLOVER_BILINEAR((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR), 1D),
|
||||
CLOVER_BILINEAR_STARCAST_3((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR_STARCAST_3), 1D),
|
||||
CLOVER_BILINEAR_STARCAST_6((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR_STARCAST_6), 1D),
|
||||
CLOVER_BILINEAR_STARCAST_9((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR_STARCAST_9), 1D),
|
||||
CLOVER_BILINEAR_STARCAST_12((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BILINEAR_STARCAST_12), 1D),
|
||||
CLOVER_BICUBIC((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.BICUBIC), 1D),
|
||||
CLOVER_HERMITE((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE), 1D),
|
||||
CLOVER_STARCAST_3((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.STARCAST_3), 1D),
|
||||
CLOVER_STARCAST_6((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.STARCAST_6), 1D),
|
||||
CLOVER_STARCAST_9((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.STARCAST_9), 1D),
|
||||
CLOVER_STARCAST_12((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.STARCAST_12), 1D),
|
||||
CLOVER_HERMITE_STARCAST_3((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE_STARCAST_3), 1D),
|
||||
CLOVER_HERMITE_STARCAST_6((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE_STARCAST_6), 1D),
|
||||
CLOVER_HERMITE_STARCAST_9((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE_STARCAST_9), 1D),
|
||||
CLOVER_HERMITE_STARCAST_12((s) -> new InterpolatedNoise(s, CLOVER, InterpolationMethod.HERMITE_STARCAST_12), 1D),
|
||||
HEXAGON(HexagonNoise::new, 2D / 64D),
|
||||
HEXAGON_BILINEAR((s) -> new InterpolatedNoise(s, HEXAGON, InterpolationMethod.BILINEAR), 1D),
|
||||
HEXAGON_BICUBIC((s) -> new InterpolatedNoise(s, HEXAGON, InterpolationMethod.BICUBIC), 1D),
|
||||
HEXAGON_HERMITE((s) -> new InterpolatedNoise(s, HEXAGON, InterpolationMethod.HERMITE), 1D),
|
||||
HEX_JAMES(HexJamesNoise::new, 2D / 64D),
|
||||
HEX_JAMES_BILINEAR((s) -> new InterpolatedNoise(s, HEX_JAMES, InterpolationMethod.BILINEAR), 1D),
|
||||
HEX_JAMES_BICUBIC((s) -> new InterpolatedNoise(s, HEX_JAMES, InterpolationMethod.BICUBIC), 1D),
|
||||
HEX_JAMES_HERMITE((s) -> new InterpolatedNoise(s, HEX_JAMES, InterpolationMethod.HERMITE), 1D),
|
||||
HEX_SIMPLEX(HexSimplexNoise::new, 2D / 64D),
|
||||
HEX_SIMPLEX_BILINEAR((s) -> new InterpolatedNoise(s, HEX_SIMPLEX, InterpolationMethod.BILINEAR), 1D),
|
||||
HEX_SIMPLEX_BICUBIC((s) -> new InterpolatedNoise(s, HEX_SIMPLEX, InterpolationMethod.BICUBIC), 1D),
|
||||
HEX_SIMPLEX_HERMITE((s) -> new InterpolatedNoise(s, HEX_SIMPLEX, InterpolationMethod.HERMITE), 1D),
|
||||
HEX_RANDOM_SIZE(HexRandomSizeNoise::new, 2D / 64D),
|
||||
HEX_RANDOM_SIZE_BILINEAR((s) -> new InterpolatedNoise(s, HEX_RANDOM_SIZE, InterpolationMethod.BILINEAR), 1D),
|
||||
HEX_RANDOM_SIZE_BICUBIC((s) -> new InterpolatedNoise(s, HEX_RANDOM_SIZE, InterpolationMethod.BICUBIC), 1D),
|
||||
HEX_RANDOM_SIZE_HERMITE((s) -> new InterpolatedNoise(s, HEX_RANDOM_SIZE, InterpolationMethod.HERMITE), 1D),
|
||||
SIERPINSKI_TRIANGLE(SierpinskiTriangleNoise::new, 8D / 64D),
|
||||
SIERPINSKI_TRIANGLE_BILINEAR((s) -> new InterpolatedNoise(s, SIERPINSKI_TRIANGLE, InterpolationMethod.BILINEAR), 1D),
|
||||
SIERPINSKI_TRIANGLE_BICUBIC((s) -> new InterpolatedNoise(s, SIERPINSKI_TRIANGLE, InterpolationMethod.BICUBIC), 1D),
|
||||
SIERPINSKI_TRIANGLE_HERMITE((s) -> new InterpolatedNoise(s, SIERPINSKI_TRIANGLE, InterpolationMethod.HERMITE), 1D),
|
||||
VASCULAR(VascularNoise::new);
|
||||
|
||||
private final NoiseFactory f;
|
||||
private final double coordinateScale;
|
||||
|
||||
NoiseType(NoiseFactory f) {
|
||||
this(f, 100D / 64D);
|
||||
}
|
||||
|
||||
NoiseType(NoiseFactory f, double coordinateScale) {
|
||||
this.f = f;
|
||||
this.coordinateScale = coordinateScale;
|
||||
}
|
||||
|
||||
public double getCoordinateScale() {
|
||||
return coordinateScale;
|
||||
}
|
||||
|
||||
public NoiseGenerator create(long seed) {
|
||||
|
||||
@@ -5,7 +5,7 @@ import art.arcane.volmlib.util.math.RNG;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
public class OffsetNoiseGenerator implements NoiseGenerator {
|
||||
public class OffsetNoiseGenerator implements NoiseGenerator, OctaveNoise {
|
||||
private static final int GENERIC = 0;
|
||||
private static final int SIMPLEX = 1;
|
||||
private static final int PERLIN = 2;
|
||||
@@ -102,6 +102,13 @@ public class OffsetNoiseGenerator implements NoiseGenerator {
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOctaves(int octaves) {
|
||||
if (base instanceof OctaveNoise octaveNoise) {
|
||||
octaveNoise.setOctaves(octaves);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNoScale() {
|
||||
return base.isNoScale();
|
||||
|
||||
@@ -23,9 +23,11 @@ import art.arcane.volmlib.util.math.RNG;
|
||||
public class PerlinNoise implements NoiseGenerator, OctaveNoise {
|
||||
private final FastNoiseDouble n;
|
||||
private int octaves;
|
||||
private double octaveBounding = 1D;
|
||||
|
||||
public PerlinNoise(long seed) {
|
||||
this.n = new FastNoiseDouble(new RNG(seed).lmax());
|
||||
n.setLongerp(FastNoiseDouble.Longerp.Qulongic);
|
||||
octaves = 1;
|
||||
}
|
||||
|
||||
@@ -35,128 +37,74 @@ public class PerlinNoise implements NoiseGenerator, OctaveNoise {
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
if (octaves <= 1) {
|
||||
return f(n.GetPerlin(x, 0));
|
||||
}
|
||||
|
||||
double f = 1;
|
||||
double m = 0;
|
||||
double v = 0;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
v += n.GetPerlin((x * (f == 1 ? f++ : (f *= 2))), 0) * f;
|
||||
m += f;
|
||||
}
|
||||
|
||||
return f(v / m);
|
||||
return f(noiseSigned(x));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noiseSigned(double x) {
|
||||
if (octaves <= 1) {
|
||||
if (octaves == 1) {
|
||||
return n.GetPerlin(x, 0D);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double magnitude = 0D;
|
||||
double amplitude = 1D;
|
||||
double value = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
double sampleFrequency;
|
||||
if (frequency == 1D) {
|
||||
sampleFrequency = frequency;
|
||||
frequency = 2D;
|
||||
} else {
|
||||
frequency *= 2D;
|
||||
sampleFrequency = frequency;
|
||||
}
|
||||
|
||||
value += n.GetPerlin(x * sampleFrequency, 0D) * frequency;
|
||||
magnitude += frequency;
|
||||
value += n.GetPerlin(x * frequency, 0D) * amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
return value / magnitude;
|
||||
return value * octaveBounding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
if (octaves <= 1) {
|
||||
return f(n.GetPerlin(x, z));
|
||||
}
|
||||
double f = 1;
|
||||
double m = 0;
|
||||
double v = 0;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
f = f == 1 ? f + 1 : f * 2;
|
||||
v += n.GetPerlin((x * f), (z * f)) * f;
|
||||
m += f;
|
||||
}
|
||||
|
||||
return f(v / m);
|
||||
return f(noiseSigned(x, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noiseSigned(double x, double z) {
|
||||
if (octaves <= 1) {
|
||||
if (octaves == 1) {
|
||||
return n.GetPerlin(x, z);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double magnitude = 0D;
|
||||
double amplitude = 1D;
|
||||
double value = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
double octaveFrequency = frequency == 1D ? frequency + 1D : frequency * 2D;
|
||||
value += n.GetPerlin(x * octaveFrequency, z * octaveFrequency) * octaveFrequency;
|
||||
magnitude += octaveFrequency;
|
||||
frequency = octaveFrequency;
|
||||
value += n.GetPerlin(x * frequency, z * frequency) * amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
return value / magnitude;
|
||||
return value * octaveBounding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
if (octaves <= 1) {
|
||||
return f(n.GetPerlin(x, y, z));
|
||||
}
|
||||
double f = 1;
|
||||
double m = 0;
|
||||
double v = 0;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
f = f == 1 ? f + 1 : f * 2;
|
||||
v += n.GetPerlin((x * f), (y * f), (z * f)) * f;
|
||||
m += f;
|
||||
}
|
||||
|
||||
return f(v / m);
|
||||
return f(noiseSigned(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noiseSigned(double x, double y, double z) {
|
||||
if (octaves <= 1) {
|
||||
if (octaves == 1) {
|
||||
return n.GetPerlin(x, y, z);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double magnitude = 0D;
|
||||
double amplitude = 1D;
|
||||
double value = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
double octaveFrequency = frequency == 1D ? frequency + 1D : frequency * 2D;
|
||||
value += n.GetPerlin(x * octaveFrequency, y * octaveFrequency, z * octaveFrequency) * octaveFrequency;
|
||||
magnitude += octaveFrequency;
|
||||
frequency = octaveFrequency;
|
||||
value += n.GetPerlin(x * frequency, y * frequency, z * frequency) * amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
return value / magnitude;
|
||||
return value * octaveBounding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOctaves(int o) {
|
||||
octaves = o;
|
||||
public void setOctaves(int octaves) {
|
||||
this.octaves = Math.max(1, Math.min(16, octaves));
|
||||
octaveBounding = 1D / (2D - Math.scalb(1D, 1 - this.octaves));
|
||||
}
|
||||
|
||||
public NoiseGenerator hermite() {
|
||||
|
||||
+45
-74
@@ -3,96 +3,67 @@ package art.arcane.iris.util.project.noise;
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
|
||||
public class SierpinskiTriangleNoise implements NoiseGenerator, OctaveNoise {
|
||||
private static final double TRI_SCALE = 0.18D;
|
||||
private static final double TRI_PROJECTION = 0.8660254037844386D;
|
||||
private static final double HEAT_SCALE = 0.33D;
|
||||
private final SimplexNoise heatSimplex;
|
||||
private int octaves;
|
||||
private static final double TRIANGLE_SIDE = 8D;
|
||||
private static final double INVERSE_HEIGHT = 2D / (Math.sqrt(3D) * TRIANGLE_SIDE);
|
||||
private static final double HEAT_SCALE = 6D;
|
||||
private static final int DEPTH = 4;
|
||||
private final SimplexNoise heat;
|
||||
|
||||
public SierpinskiTriangleNoise(long seed) {
|
||||
RNG rng = new RNG(seed);
|
||||
this.heatSimplex = new SimplexNoise(rng.nextParallelRNG(177L).lmax());
|
||||
this.octaves = 1;
|
||||
}
|
||||
|
||||
private double clip(double value) {
|
||||
if (value < 0D) {
|
||||
return 0D;
|
||||
}
|
||||
|
||||
if (value > 1D) {
|
||||
return 1D;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
private double heat(double x, double z) {
|
||||
if (octaves <= 1) {
|
||||
return heatSimplex.noise(x * HEAT_SCALE, z * HEAT_SCALE);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double amplitude = 1D;
|
||||
double total = 0D;
|
||||
double max = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
total += heatSimplex.noise((x * HEAT_SCALE) * frequency, (z * HEAT_SCALE) * frequency) * amplitude;
|
||||
max += amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
if (max == 0D) {
|
||||
return 0.5D;
|
||||
}
|
||||
|
||||
return clip(total / max);
|
||||
}
|
||||
|
||||
private double mask(double x, double z) {
|
||||
double sx = (x * TRI_SCALE) + ((z * TRI_SCALE) * 0.5D);
|
||||
double sz = (z * TRI_SCALE) * TRI_PROJECTION;
|
||||
long ix = (long) Math.floor(Math.abs(sx));
|
||||
long iz = (long) Math.floor(Math.abs(sz));
|
||||
return ((ix & iz) == 0L) ? 1D : 0D;
|
||||
}
|
||||
|
||||
private double sample(double x, double z) {
|
||||
double m = mask(x, z);
|
||||
double h = heat(x, z);
|
||||
if (m >= 0.5D) {
|
||||
return clip((h * 0.65D) + 0.35D);
|
||||
}
|
||||
|
||||
return clip(h * 0.12D);
|
||||
this.heat = new SimplexNoise(new RNG(seed).nextParallelRNG(177L).lmax());
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
return sample(x, 0D);
|
||||
return sample(x, 0D, 0D);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
return sample(x, z);
|
||||
return sample(x, 0D, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
if (z == 0D) {
|
||||
return sample(x, y);
|
||||
}
|
||||
|
||||
double a = sample(x, z);
|
||||
double b = sample(y, x);
|
||||
double c = sample(z, y);
|
||||
return (a + b + c) / 3D;
|
||||
return sample(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOctaves(int o) {
|
||||
this.octaves = Math.max(1, o);
|
||||
public void setOctaves(int octaves) {
|
||||
heat.setOctaves(octaves);
|
||||
}
|
||||
|
||||
private boolean contains(double x, double z) {
|
||||
double v = z * INVERSE_HEIGHT;
|
||||
double u = (x / TRIANGLE_SIDE) - (v * 0.5D);
|
||||
u -= Math.floor(u);
|
||||
v -= Math.floor(v);
|
||||
|
||||
if (u + v > 1D) {
|
||||
u = 1D - u;
|
||||
v = 1D - v;
|
||||
}
|
||||
|
||||
for (int depth = 0; depth < DEPTH; depth++) {
|
||||
if (u >= 0.5D) {
|
||||
u = (u * 2D) - 1D;
|
||||
v *= 2D;
|
||||
} else if (v >= 0.5D) {
|
||||
u *= 2D;
|
||||
v = (v * 2D) - 1D;
|
||||
} else if (u + v <= 0.5D) {
|
||||
u *= 2D;
|
||||
v *= 2D;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private double sample(double x, double y, double z) {
|
||||
double value = heat.noise(x * HEAT_SCALE, y * HEAT_SCALE, z * HEAT_SCALE);
|
||||
return contains(x, z) ? (value * 0.65D) + 0.35D : value * 0.12D;
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@ import art.arcane.volmlib.util.math.RNG;
|
||||
public class SimplexNoise implements NoiseGenerator, OctaveNoise {
|
||||
private final FastNoiseDouble n;
|
||||
private int octaves;
|
||||
private double octaveBounding = 1D;
|
||||
|
||||
public SimplexNoise(long seed) {
|
||||
this.n = new FastNoiseDouble(new RNG(seed).lmax());
|
||||
@@ -35,127 +36,74 @@ public class SimplexNoise implements NoiseGenerator, OctaveNoise {
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
if (octaves <= 1) {
|
||||
return f(n.GetSimplex(x, 0d));
|
||||
}
|
||||
|
||||
double f = 1;
|
||||
double m = 0;
|
||||
double v = 0;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
v += n.GetSimplex((x * (f == 1 ? f++ : (f *= 2))), 0d) * f;
|
||||
m += f;
|
||||
}
|
||||
|
||||
return f(v / m);
|
||||
return f(noiseSigned(x));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noiseSigned(double x) {
|
||||
if (octaves <= 1) {
|
||||
if (octaves == 1) {
|
||||
return n.GetSimplex(x, 0D);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double magnitude = 0D;
|
||||
double amplitude = 1D;
|
||||
double value = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
double sampleFrequency;
|
||||
if (frequency == 1D) {
|
||||
sampleFrequency = frequency;
|
||||
frequency = 2D;
|
||||
} else {
|
||||
frequency *= 2D;
|
||||
sampleFrequency = frequency;
|
||||
}
|
||||
|
||||
value += n.GetSimplex(x * sampleFrequency, 0D) * frequency;
|
||||
magnitude += frequency;
|
||||
value += n.GetSimplex(x * frequency, 0D) * amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
return value / magnitude;
|
||||
return value * octaveBounding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
if (octaves <= 1) {
|
||||
return f(n.GetSimplex(x, z));
|
||||
}
|
||||
double f = 1;
|
||||
double m = 0;
|
||||
double v = 0;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
f = f == 1 ? f + 1 : f * 2;
|
||||
v += n.GetSimplex((x * f), (z * f)) * f;
|
||||
m += f;
|
||||
}
|
||||
|
||||
return f(v / m);
|
||||
return f(noiseSigned(x, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noiseSigned(double x, double z) {
|
||||
if (octaves <= 1) {
|
||||
if (octaves == 1) {
|
||||
return n.GetSimplex(x, z);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double magnitude = 0D;
|
||||
double amplitude = 1D;
|
||||
double value = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
double octaveFrequency = frequency == 1D ? frequency + 1D : frequency * 2D;
|
||||
value += n.GetSimplex(x * octaveFrequency, z * octaveFrequency) * octaveFrequency;
|
||||
magnitude += octaveFrequency;
|
||||
frequency = octaveFrequency;
|
||||
value += n.GetSimplex(x * frequency, z * frequency) * amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
return value / magnitude;
|
||||
return value * octaveBounding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
if (octaves <= 1) {
|
||||
return f(n.GetSimplex(x, y, z));
|
||||
}
|
||||
double f = 1;
|
||||
double m = 0;
|
||||
double v = 0;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
f = f == 1 ? f + 1 : f * 2;
|
||||
v += n.GetSimplex((x * f), (y * f), (z * f)) * f;
|
||||
m += f;
|
||||
}
|
||||
|
||||
return f(v / m);
|
||||
return f(noiseSigned(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noiseSigned(double x, double y, double z) {
|
||||
if (octaves <= 1) {
|
||||
if (octaves == 1) {
|
||||
return n.GetSimplex(x, y, z);
|
||||
}
|
||||
|
||||
double frequency = 1D;
|
||||
double magnitude = 0D;
|
||||
double amplitude = 1D;
|
||||
double value = 0D;
|
||||
|
||||
for (int i = 0; i < octaves; i++) {
|
||||
double octaveFrequency = frequency == 1D ? frequency + 1D : frequency * 2D;
|
||||
value += n.GetSimplex(x * octaveFrequency, y * octaveFrequency, z * octaveFrequency) * octaveFrequency;
|
||||
magnitude += octaveFrequency;
|
||||
frequency = octaveFrequency;
|
||||
value += n.GetSimplex(x * frequency, y * frequency, z * frequency) * amplitude;
|
||||
frequency *= 2D;
|
||||
amplitude *= 0.5D;
|
||||
}
|
||||
|
||||
return value / magnitude;
|
||||
return value * octaveBounding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOctaves(int o) {
|
||||
octaves = o;
|
||||
public void setOctaves(int octaves) {
|
||||
this.octaves = Math.max(1, Math.min(16, octaves));
|
||||
octaveBounding = 1D / (2D - Math.scalb(1D, 1 - this.octaves));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,7 +31,7 @@ public class VascularNoise implements NoiseGenerator {
|
||||
}
|
||||
|
||||
private double filter(double noise) {
|
||||
double normalized = (noise * 0.5D) + 0.5D;
|
||||
double normalized = 0.5D - noise * 0.5D;
|
||||
if (normalized < 0D) {
|
||||
return 0D;
|
||||
}
|
||||
@@ -40,6 +40,7 @@ public class VascularNoise implements NoiseGenerator {
|
||||
}
|
||||
|
||||
private double filterSigned(double noise) {
|
||||
noise = -noise;
|
||||
if (noise < -1D) {
|
||||
return -1D;
|
||||
}
|
||||
|
||||
@@ -18,13 +18,11 @@
|
||||
|
||||
package art.arcane.iris.util.project.noise;
|
||||
|
||||
import art.arcane.volmlib.util.math.RNG;
|
||||
|
||||
public class WhiteNoise implements NoiseGenerator {
|
||||
private final FastNoise n;
|
||||
private final FastNoiseDouble n;
|
||||
|
||||
public WhiteNoise(long seed) {
|
||||
n = new FastNoise(new RNG(seed).imax());
|
||||
n = new FastNoiseDouble(seed);
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
@@ -35,22 +33,18 @@ public class WhiteNoise implements NoiseGenerator {
|
||||
return true;
|
||||
}
|
||||
|
||||
private double f(double m) {
|
||||
return (m % 8192) * 1024;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x) {
|
||||
return (n.GetWhiteNoise(f(x), 0d) / 2D) + 0.5D;
|
||||
return (n.GetWhiteNoise(x, 0d) / 2D) + 0.5D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double z) {
|
||||
return (n.GetWhiteNoise(f(x), f(z)) / 2D) + 0.5D;
|
||||
return (n.GetWhiteNoise(x, z) / 2D) + 0.5D;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double noise(double x, double y, double z) {
|
||||
return (n.GetWhiteNoise(f(x), f(y), f(z)) / 2D) + 0.5D;
|
||||
return (n.GetWhiteNoise(x, y, z) / 2D) + 0.5D;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user