pass seed to noise functions

This commit is contained in:
dfsek 2021-07-19 19:24:54 -07:00
parent 7acfc5e3d0
commit 3bf8fe7901
79 changed files with 299 additions and 382 deletions

View File

@ -29,7 +29,7 @@ public class ImageBiomeProvider implements BiomeProvider, SeededBuilder<BiomePro
} }
@Override @Override
public TerraBiome getBiome(int x, int z) { public TerraBiome getBiome(int x, int z, long seed) {
x /= resolution; x /= resolution;
z /= resolution; z /= resolution;
Color color = align.getColor(image, x, z); Color color = align.getColor(image, x, z);

View File

@ -29,7 +29,7 @@ public class BiomeHolderImpl implements BiomeHolder {
} }
@Override @Override
public BiomeHolder expand(BiomeExpander expander) { public BiomeHolder expand(BiomeExpander expander, long seed) {
TerraBiome[][] old = biomes; TerraBiome[][] old = biomes;
int newWidth = width * 2 - 1; int newWidth = width * 2 - 1;
@ -39,31 +39,31 @@ public class BiomeHolderImpl implements BiomeHolder {
for(int z = 0; z < width; z++) { for(int z = 0; z < width; z++) {
biomes[x * 2][z * 2] = old[x][z]; biomes[x * 2][z * 2] = old[x][z];
if(z != width - 1) if(z != width - 1)
biomes[x * 2][z * 2 + 1] = expander.getBetween(x + origin.getX(), z + 1 + origin.getZ(), old[x][z], old[x][z + 1]); biomes[x * 2][z * 2 + 1] = expander.getBetween(x + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z], old[x][z + 1]);
if(x != width - 1) if(x != width - 1)
biomes[x * 2 + 1][z * 2] = expander.getBetween(x + 1 + origin.getX(), z + origin.getZ(), old[x][z], old[x + 1][z]); biomes[x * 2 + 1][z * 2] = expander.getBetween(x + 1 + origin.getX(), z + origin.getZ(), seed, old[x][z], old[x + 1][z]);
if(x != width - 1 && z != width - 1) if(x != width - 1 && z != width - 1)
biomes[x * 2 + 1][z * 2 + 1] = expander.getBetween(x + 1 + origin.getX(), z + 1 + origin.getZ(), old[x][z], old[x + 1][z + 1], old[x][z + 1], old[x + 1][z]); biomes[x * 2 + 1][z * 2 + 1] = expander.getBetween(x + 1 + origin.getX(), z + 1 + origin.getZ(), seed, old[x][z], old[x + 1][z + 1], old[x][z + 1], old[x + 1][z]);
} }
} }
return new BiomeHolderImpl(biomes, origin.setX(origin.getX() * 2 - 1).setZ(origin.getZ() * 2 - 1), newWidth, offset); return new BiomeHolderImpl(biomes, origin.setX(origin.getX() * 2 - 1).setZ(origin.getZ() * 2 - 1), newWidth, offset);
} }
@Override @Override
public void mutate(BiomeMutator mutator) { public void mutate(BiomeMutator mutator, long seed) {
for(int x = 0; x < width; x++) { for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) { for(int z = 0; z < width; z++) {
BiomeMutator.ViewPoint viewPoint = new BiomeMutator.ViewPoint(this, x, z); BiomeMutator.ViewPoint viewPoint = new BiomeMutator.ViewPoint(this, x, z);
biomes[x][z] = mutator.mutate(viewPoint, x + origin.getX(), z + origin.getZ()); biomes[x][z] = mutator.mutate(viewPoint, x + origin.getX(), z + origin.getZ(), seed);
} }
} }
} }
@Override @Override
public void fill(BiomeSource source) { public void fill(BiomeSource source, long seed) {
for(int x = 0; x < width; x++) { for(int x = 0; x < width; x++) {
for(int z = 0; z < width; z++) { for(int z = 0; z < width; z++) {
biomes[x][z] = source.getBiome(origin.getX() + x, origin.getZ() + z); biomes[x][z] = source.getBiome(origin.getX() + x, origin.getZ() + z, seed);
} }
} }
} }

View File

@ -29,10 +29,10 @@ public class BiomePipelineImpl {
* @param z Chunk Z coord * @param z Chunk Z coord
* @return BiomeHolder containing biomes. * @return BiomeHolder containing biomes.
*/ */
public BiomeHolder getBiomes(int x, int z) { public BiomeHolder getBiomes(int x, int z, long seed) {
BiomeHolder holder = new BiomeHolderImpl(init, new Vector2(x * (init - 1), z * (init - 1))); BiomeHolder holder = new BiomeHolderImpl(init, new Vector2(x * (init - 1), z * (init - 1)));
holder.fill(source); holder.fill(source, seed);
for(Stage stage : stages) holder = stage.apply(holder); for(Stage stage : stages) holder = stage.apply(holder, seed);
return holder; return holder;
} }

View File

@ -13,25 +13,23 @@ import net.jafama.FastMath;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class StandardBiomeProvider implements BiomeProvider { public class StandardBiomeProvider implements BiomeProvider {
private final LoadingCache<Vector2, BiomeHolder> holderCache; private final LoadingCache<SeededVector, BiomeHolder> holderCache;
private final BiomePipelineImpl pipeline; private final BiomePipelineImpl pipeline;
private final int resolution; private final int resolution;
private final NoiseSampler mutator; private final NoiseSampler mutator;
private final double noiseAmp; private final double noiseAmp;
private final int seed;
public StandardBiomeProvider(BiomePipelineImpl pipeline, TerraPlugin main, int resolution, NoiseSampler mutator, double noiseAmp, int seed) { public StandardBiomeProvider(BiomePipelineImpl pipeline, TerraPlugin main, int resolution, NoiseSampler mutator, double noiseAmp, int seed) {
this.resolution = resolution; this.resolution = resolution;
this.mutator = mutator; this.mutator = mutator;
this.noiseAmp = noiseAmp; this.noiseAmp = noiseAmp;
this.seed = seed;
holderCache = CacheBuilder.newBuilder() holderCache = CacheBuilder.newBuilder()
.maximumSize(main == null ? 32 : main.getTerraConfig().getProviderCache()) .maximumSize(main == null ? 32 : main.getTerraConfig().getProviderCache())
.build( .build(
new CacheLoader<Vector2, BiomeHolder>() { new CacheLoader<SeededVector, BiomeHolder>() {
@Override @Override
public BiomeHolder load(@NotNull Vector2 key) { public BiomeHolder load(@NotNull SeededVector key) {
return pipeline.getBiomes(key.getBlockX(), key.getBlockZ()); return pipeline.getBiomes(key.x, key.z, key.seed);
} }
} }
); );
@ -39,9 +37,9 @@ public class StandardBiomeProvider implements BiomeProvider {
} }
@Override @Override
public TerraBiome getBiome(int x, int z) { public TerraBiome getBiome(int x, int z, long seed) {
x += mutator.getNoiseSeeded(seed, x, z) * noiseAmp; x += mutator.getNoiseSeeded(seed + 1, x, z) * noiseAmp;
z += mutator.getNoiseSeeded(1 + seed, x, z) * noiseAmp; z += mutator.getNoiseSeeded(seed + 2, x, z) * noiseAmp;
x = FastMath.floorToInt(FastMath.floorDiv(x, resolution)); x = FastMath.floorToInt(FastMath.floorDiv(x, resolution));
@ -50,6 +48,35 @@ public class StandardBiomeProvider implements BiomeProvider {
int fdX = FastMath.floorDiv(x, pipeline.getSize()); int fdX = FastMath.floorDiv(x, pipeline.getSize());
int fdZ = FastMath.floorDiv(z, pipeline.getSize()); int fdZ = FastMath.floorDiv(z, pipeline.getSize());
return holderCache.getUnchecked(new Vector2(fdX, fdZ)).getBiome(x - fdX * pipeline.getSize(), z - fdZ * pipeline.getSize()); return holderCache.getUnchecked(new SeededVector(fdX, fdZ, seed)).getBiome(x - fdX * pipeline.getSize(), z - fdZ * pipeline.getSize());
}
private static final class SeededVector {
private final int x;
private final int z;
private final long seed;
private SeededVector(int x, int z, long seed) {
this.x = x;
this.z = z;
this.seed = seed;
}
@Override
public int hashCode() {
int result = 0;
result = 31 * result + ((int) (seed ^ (seed >>> 32)));
result = 31 * result + x;
result = 31 * result + z;
return result;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof SeededVector)) return false;
SeededVector that = (SeededVector) obj;
return this.seed == that.seed && this.x == that.x && this.z == that.z;
}
} }
} }

View File

@ -3,5 +3,5 @@ package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
public interface BiomeExpander { public interface BiomeExpander {
TerraBiome getBetween(double x, double z, TerraBiome... others); TerraBiome getBetween(double x, double z, long seed, TerraBiome... others);
} }

View File

@ -4,11 +4,11 @@ import com.dfsek.terra.api.world.biome.TerraBiome;
import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource; import com.dfsek.terra.api.world.biome.generation.pipeline.BiomeSource;
public interface BiomeHolder { public interface BiomeHolder {
BiomeHolder expand(BiomeExpander expander); BiomeHolder expand(BiomeExpander expander, long seed);
void mutate(BiomeMutator mutator); void mutate(BiomeMutator mutator, long seed);
void fill(BiomeSource source); void fill(BiomeSource source, long seed);
TerraBiome getBiome(int x, int z); TerraBiome getBiome(int x, int z);

View File

@ -3,7 +3,7 @@ package com.dfsek.terra.addons.biome.pipeline.api;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
public interface BiomeMutator { public interface BiomeMutator {
TerraBiome mutate(ViewPoint viewPoint, double x, double z); TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed);
class ViewPoint { class ViewPoint {
private final BiomeHolder biomes; private final BiomeHolder biomes;

View File

@ -3,6 +3,6 @@ package com.dfsek.terra.addons.biome.pipeline.api;
public interface Stage { public interface Stage {
boolean isExpansion(); boolean isExpansion();
BiomeHolder apply(BiomeHolder in); BiomeHolder apply(BiomeHolder in, long seed);
} }

View File

@ -13,7 +13,7 @@ public class FractalExpander implements BiomeExpander {
} }
@Override @Override
public TerraBiome getBetween(double x, double z, TerraBiome... others) { public TerraBiome getBetween(double x, double z, long seed, TerraBiome... others) {
return others[MathUtil.normalizeIndex(sampler.getNoise(x, z), others.length)]; return others[MathUtil.normalizeIndex(sampler.getNoiseSeeded(seed, x, z), others.length)];
} }
} }

View File

@ -23,7 +23,7 @@ public class BorderListMutator implements BiomeMutator {
} }
@Override @Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z) { public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
TerraBiome origin = viewPoint.getBiome(0, 0); TerraBiome origin = viewPoint.getBiome(0, 0);
if(origin.getTags().contains(defaultReplace)) { if(origin.getTags().contains(defaultReplace)) {
for(int xi = -1; xi <= 1; xi++) { for(int xi = -1; xi <= 1; xi++) {
@ -33,10 +33,10 @@ public class BorderListMutator implements BiomeMutator {
if(current == null) continue; if(current == null) continue;
if(current.getTags().contains(border)) { if(current.getTags().contains(border)) {
if(replace.containsKey(origin)) { if(replace.containsKey(origin)) {
TerraBiome biome = replace.get(origin).get(noiseSampler, x, z); TerraBiome biome = replace.get(origin).get(noiseSampler, x, z, seed);
return biome == null ? origin : biome; return biome == null ? origin : biome;
} }
TerraBiome biome = replaceDefault.get(noiseSampler, x, z); TerraBiome biome = replaceDefault.get(noiseSampler, x, z, seed);
return biome == null ? origin : biome; return biome == null ? origin : biome;
} }
} }

View File

@ -19,7 +19,7 @@ public class BorderMutator implements BiomeMutator {
} }
@Override @Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z) { public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
TerraBiome origin = viewPoint.getBiome(0, 0); TerraBiome origin = viewPoint.getBiome(0, 0);
if(origin.getTags().contains(replaceTag)) { if(origin.getTags().contains(replaceTag)) {
for(int xi = -1; xi <= 1; xi++) { for(int xi = -1; xi <= 1; xi++) {
@ -28,7 +28,7 @@ public class BorderMutator implements BiomeMutator {
TerraBiome current = viewPoint.getBiome(xi, zi); TerraBiome current = viewPoint.getBiome(xi, zi);
if(current == null) continue; if(current == null) continue;
if(current.getTags().contains(border)) { if(current.getTags().contains(border)) {
TerraBiome biome = replace.get(noiseSampler, x, z); TerraBiome biome = replace.get(noiseSampler, x, z, seed);
return biome == null ? origin : biome; return biome == null ? origin : biome;
} }
} }

View File

@ -21,14 +21,14 @@ public class ReplaceListMutator implements BiomeMutator {
} }
@Override @Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z) { public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
TerraBiome center = viewPoint.getBiome(0, 0); TerraBiome center = viewPoint.getBiome(0, 0);
if(replace.containsKey(center)) { if(replace.containsKey(center)) {
TerraBiome biome = replace.get(center).get(sampler, x, z); TerraBiome biome = replace.get(center).get(sampler, x, z, seed);
return biome == null ? viewPoint.getBiome(0, 0) : biome; return biome == null ? viewPoint.getBiome(0, 0) : biome;
} }
if(viewPoint.getBiome(0, 0).getTags().contains(defaultTag)) { if(viewPoint.getBiome(0, 0).getTags().contains(defaultTag)) {
TerraBiome biome = replaceDefault.get(sampler, x, z); TerraBiome biome = replaceDefault.get(sampler, x, z, seed);
return biome == null ? viewPoint.getBiome(0, 0) : biome; return biome == null ? viewPoint.getBiome(0, 0) : biome;
} }
return center; return center;

View File

@ -17,9 +17,9 @@ public class ReplaceMutator implements BiomeMutator {
} }
@Override @Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z) { public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
if(viewPoint.getBiome(0, 0).getTags().contains(replaceableTag)) { if(viewPoint.getBiome(0, 0).getTags().contains(replaceableTag)) {
TerraBiome biome = replace.get(sampler, x, z); TerraBiome biome = replace.get(sampler, x, z, seed);
return biome == null ? viewPoint.getBiome(0, 0) : biome; return biome == null ? viewPoint.getBiome(0, 0) : biome;
} }
return viewPoint.getBiome(0, 0); return viewPoint.getBiome(0, 0);

View File

@ -16,7 +16,7 @@ public class SmoothMutator implements BiomeMutator {
} }
@Override @Override
public TerraBiome mutate(ViewPoint viewPoint, double x, double z) { public TerraBiome mutate(ViewPoint viewPoint, double x, double z, long seed) {
TerraBiome top = viewPoint.getBiome(1, 0); TerraBiome top = viewPoint.getBiome(1, 0);
TerraBiome bottom = viewPoint.getBiome(-1, 0); TerraBiome bottom = viewPoint.getBiome(-1, 0);
TerraBiome left = viewPoint.getBiome(0, 1); TerraBiome left = viewPoint.getBiome(0, 1);
@ -27,7 +27,7 @@ public class SmoothMutator implements BiomeMutator {
boolean horiz = Objects.equals(left, right) && left != null; boolean horiz = Objects.equals(left, right) && left != null;
if(vert && horiz) { if(vert && horiz) {
return MathUtil.normalizeIndex(sampler.getNoise(x, z), 2) == 0 ? left : top; return MathUtil.normalizeIndex(sampler.getNoiseSeeded(seed, x, z), 2) == 0 ? left : top;
} }
if(vert) return top; if(vert) return top;

View File

@ -15,7 +15,7 @@ public class RandomSource implements BiomeSource {
} }
@Override @Override
public TerraBiome getBiome(double x, double z) { public TerraBiome getBiome(double x, double z, long seed) {
return biomes.get(sampler, x, z); return biomes.get(sampler, x, z, seed);
} }
} }

View File

@ -17,8 +17,8 @@ public class ExpanderStage implements Stage {
} }
@Override @Override
public BiomeHolder apply(BiomeHolder in) { public BiomeHolder apply(BiomeHolder in, long seed) {
return in.expand(expander); return in.expand(expander, seed);
} }
public enum Type { public enum Type {

View File

@ -17,8 +17,8 @@ public class MutatorStage implements Stage {
} }
@Override @Override
public BiomeHolder apply(BiomeHolder in) { public BiomeHolder apply(BiomeHolder in, long seed) {
in.mutate(mutator); in.mutate(mutator, seed);
return in; return in;
} }

View File

@ -12,7 +12,7 @@ public class SingleBiomeProvider implements BiomeProvider, SeededBuilder<BiomePr
} }
@Override @Override
public TerraBiome getBiome(int x, int z) { public TerraBiome getBiome(int x, int z, long seed) {
return biome; return biome;
} }

View File

@ -47,14 +47,15 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
try(ProfileFrame ignore = main.getProfiler().profile("biomes")) { try(ProfileFrame ignore = main.getProfiler().profile("biomes")) {
int xOrig = (chunkX << 4); int xOrig = (chunkX << 4);
int zOrig = (chunkZ << 4); int zOrig = (chunkZ << 4);
long seed = world.getSeed();
BiomeProvider grid = main.getWorld(world).getBiomeProvider(); BiomeProvider grid = main.getWorld(world).getBiomeProvider();
for(int x = 0; x < 4; x++) { for(int x = 0; x < 4; x++) {
for(int z = 0; z < 4; z++) { for(int z = 0; z < 4; z++) {
int cx = xOrig + (x << 2); int cx = xOrig + (x << 2);
int cz = zOrig + (z << 2); int cz = zOrig + (z << 2);
TerraBiome b = grid.getBiome(cx, cz); TerraBiome b = grid.getBiome(cx, cz, seed);
biome.setBiome(cx, cz, b.getVanillaBiomes().get(b.getGenerator(world).getBiomeNoise(), cx, 0, cz)); biome.setBiome(cx, cz, b.getVanillaBiomes().get(b.getGenerator(world).getBiomeNoise(), cx, 0, cz, world.getSeed()));
} }
} }
} }
@ -82,6 +83,8 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
Sampler sampler = tw.getConfig().getSamplerCache().getChunk(chunkX, chunkZ); Sampler sampler = tw.getConfig().getSamplerCache().getChunk(chunkX, chunkZ);
long seed = world.getSeed();
for(int x = 0; x < 16; x++) { for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) { for(int z = 0; z < 16; z++) {
int paletteLevel = 0; int paletteLevel = 0;
@ -89,7 +92,7 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
int cx = xOrig + x; int cx = xOrig + x;
int cz = zOrig + z; int cz = zOrig + z;
TerraBiome biome = grid.getBiome(cx, cz); TerraBiome biome = grid.getBiome(cx, cz, seed);
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class); PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
@ -108,12 +111,12 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
if(sampler.sample(x, y, z) > 0) { if(sampler.sample(x, y, z) > 0) {
justSet = true; justSet = true;
data = PaletteUtil.getPalette(x, y, z, generator, sampler, paletteInfo).get(paletteLevel, cx, y, cz); data = PaletteUtil.getPalette(x, y, z, generator, sampler, paletteInfo).get(paletteLevel, cx, y, cz, seed);
chunk.setBlock(x, y, z, data); chunk.setBlock(x, y, z, data);
paletteLevel++; paletteLevel++;
} else if(y <= sea) { } else if(y <= sea) {
chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, y, z + zOrig)); chunk.setBlock(x, y, z, seaPalette.get(sea - y, x + xOrig, y, z + zOrig, seed));
justSet = false; justSet = false;
paletteLevel = 0; paletteLevel = 0;
@ -167,7 +170,7 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
public BlockState getBlock(World world, int x, int y, int z) { public BlockState getBlock(World world, int x, int y, int z) {
TerraWorld terraWorld = main.getWorld(world); TerraWorld terraWorld = main.getWorld(world);
BiomeProvider provider = terraWorld.getBiomeProvider(); BiomeProvider provider = terraWorld.getBiomeProvider();
TerraBiome biome = provider.getBiome(x, z); TerraBiome biome = provider.getBiome(x, z, world.getSeed());
Sampler sampler = terraWorld.getConfig().getSamplerCache().get(x, z); Sampler sampler = terraWorld.getConfig().getSamplerCache().get(x, z);
PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class); PaletteInfo paletteInfo = biome.getContext().get(PaletteInfo.class);
@ -181,9 +184,9 @@ public class NoiseChunkGenerator3D implements TerraChunkGenerator {
if(sampler.sample(fdX, yi, fdZ) > 0) level++; if(sampler.sample(fdX, yi, fdZ) > 0) level++;
else level = 0; else level = 0;
} }
return palette.get(level, x, y, z); return palette.get(level, x, y, z, world.getSeed());
} else if(y <= paletteInfo.getSeaLevel()) { } else if(y <= paletteInfo.getSeaLevel()) {
return paletteInfo.getOcean().get(paletteInfo.getSeaLevel() - y, x, y, z); return paletteInfo.getOcean().get(paletteInfo.getSeaLevel() - y, x, y, z, world.getSeed());
} else return air; } else return air;
} }
} }

View File

@ -32,11 +32,13 @@ public class ChunkInterpolator2D implements ChunkInterpolator {
int xOrigin = chunkX << 4; int xOrigin = chunkX << 4;
int zOrigin = chunkZ << 4; int zOrigin = chunkZ << 4;
long seed = w.getSeed();
double[][] noiseStorage = new double[5][5]; double[][] noiseStorage = new double[5][5];
for(int x = 0; x < 5; x++) { for(int x = 0; x < 5; x++) {
for(int z = 0; z < 5; z++) { for(int z = 0; z < 5; z++) {
Generator generator = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2)).getGenerator(w); Generator generator = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator(w);
Map<Generator, MutableInteger> genMap = new HashMap<>(); Map<Generator, MutableInteger> genMap = new HashMap<>();
int step = generator.getBlendStep(); int step = generator.getBlendStep();
@ -44,7 +46,7 @@ public class ChunkInterpolator2D implements ChunkInterpolator {
for(int xi = -blend; xi <= blend; xi++) { for(int xi = -blend; xi <= blend; xi++) {
for(int zi = -blend; zi <= blend; zi++) { for(int zi = -blend; zi <= blend; zi++) {
genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step)).getGenerator(w), g -> new MutableInteger(0)).increment(); // Increment by 1 genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(w), g -> new MutableInteger(0)).increment(); // Increment by 1
} }
} }

View File

@ -45,9 +45,11 @@ public class ChunkInterpolator3D implements ChunkInterpolator {
double[][][] noiseStorage = new double[5][5][size + 1]; double[][][] noiseStorage = new double[5][5][size + 1];
long seed = w.getSeed();
for(int x = 0; x < 5; x++) { for(int x = 0; x < 5; x++) {
for(int z = 0; z < 5; z++) { for(int z = 0; z < 5; z++) {
Generator generator = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2)).getGenerator(w); Generator generator = provider.getBiome(xOrigin + (x << 2), zOrigin + (z << 2), seed).getGenerator(w);
Map<Generator, MutableInteger> genMap = new HashMap<>(); Map<Generator, MutableInteger> genMap = new HashMap<>();
int step = generator.getBlendStep(); int step = generator.getBlendStep();
@ -55,7 +57,7 @@ public class ChunkInterpolator3D implements ChunkInterpolator {
for(int xi = -blend; xi <= blend; xi++) { for(int xi = -blend; xi <= blend; xi++) {
for(int zi = -blend; zi <= blend; zi++) { for(int zi = -blend; zi <= blend; zi++) {
genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step)).getGenerator(w), g -> new MutableInteger(0)).increment(); // Increment by 1 genMap.computeIfAbsent(provider.getBiome(xOrigin + (x << 2) + (xi * step), zOrigin + (z << 2) + (zi * step), seed).getGenerator(w), g -> new MutableInteger(0)).increment(); // Increment by 1
} }
} }

View File

@ -11,12 +11,14 @@ public class ElevationInterpolator {
int xOrigin = chunkX << 4; int xOrigin = chunkX << 4;
int zOrigin = chunkZ << 4; int zOrigin = chunkZ << 4;
long seed = world.getSeed();
Generator[][] gens = new Generator[18 + 2 * smooth][18 + 2 * smooth]; Generator[][] gens = new Generator[18 + 2 * smooth][18 + 2 * smooth];
// Precompute generators. // Precompute generators.
for(int x = -1 - smooth; x <= 16 + smooth; x++) { for(int x = -1 - smooth; x <= 16 + smooth; x++) {
for(int z = -1 - smooth; z <= 16 + smooth; z++) { for(int z = -1 - smooth; z <= 16 + smooth; z++) {
gens[x + 1 + smooth][z + 1 + smooth] = provider.getBiome(xOrigin + x, zOrigin + z).getGenerator(world); gens[x + 1 + smooth][z + 1 + smooth] = provider.getBiome(xOrigin + x, zOrigin + z, seed).getGenerator(world);
} }
} }
@ -27,7 +29,7 @@ public class ElevationInterpolator {
for(int xi = -smooth; xi <= smooth; xi++) { for(int xi = -smooth; xi <= smooth; xi++) {
for(int zi = -smooth; zi <= smooth; zi++) { for(int zi = -smooth; zi <= smooth; zi++) {
Generator gen = gens[x + 1 + smooth + xi][z + 1 + smooth + zi]; Generator gen = gens[x + 1 + smooth + xi][z + 1 + smooth + zi];
noise += gen.getElevationSampler().getNoise(xOrigin + x, zOrigin + z) * gen.getElevationWeight(); noise += gen.getElevationSampler().getNoiseSeeded(seed, xOrigin + x, zOrigin + z) * gen.getElevationWeight();
div += gen.getElevationWeight(); div += gen.getElevationWeight();
} }
} }

View File

@ -12,7 +12,7 @@ public class Sampler3D implements Sampler {
private final ElevationInterpolator elevationInterpolator; private final ElevationInterpolator elevationInterpolator;
public Sampler3D(int x, int z, BiomeProvider provider, World world, int elevationSmooth) { public Sampler3D(int x, int z, BiomeProvider provider, World world, int elevationSmooth) {
this.interpolator = new ChunkInterpolator3D(world, x, z, provider, (generator, coord) -> generator.getBaseSampler().getNoise(coord)); this.interpolator = new ChunkInterpolator3D(world, x, z, provider, (generator, coord) -> generator.getBaseSampler().getNoiseSeeded(coord, world.getSeed()));
this.elevationInterpolator = new ElevationInterpolator(world, x, z, provider, elevationSmooth); this.elevationInterpolator = new ElevationInterpolator(world, x, z, provider, elevationSmooth);
} }

View File

@ -46,7 +46,7 @@ public class AsyncBiomeFinder implements Runnable {
*/ */
public boolean isValid(int x, int z, TerraBiome target) { public boolean isValid(int x, int z, TerraBiome target) {
int res = main.getTerraConfig().getBiomeSearchResolution(); int res = main.getTerraConfig().getBiomeSearchResolution();
return getProvider().getBiome(x * res, z * res).equals(target); return getProvider().getBiome(x * res, z * res, world.getSeed()).equals(target);
} }
public Vector3 finalizeVector(Vector3 orig) { public Vector3 finalizeVector(Vector3 orig) {

View File

@ -38,7 +38,7 @@ public class BiomeCommand implements CommandTemplate {
Player player = (Player) sender; Player player = (Player) sender;
BiomeProvider provider = main.getWorld(player.world()).getBiomeProvider(); BiomeProvider provider = main.getWorld(player.world()).getBiomeProvider();
UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.position()); UserDefinedBiome biome = (UserDefinedBiome) provider.getBiome(player.position(), player.world().getSeed());
sender.sendMessage("You are standing in " + biome.getID()); sender.sendMessage("You are standing in " + biome.getID());
} }
} }

View File

@ -39,7 +39,7 @@ public class CarverCache {
List<Worm.WormPoint> points = new ArrayList<>(); List<Worm.WormPoint> points = new ArrayList<>();
for(int i = 0; i < carving.getLength(); i++) { for(int i = 0; i < carving.getLength(); i++) {
carving.step(); carving.step();
TerraBiome biome = provider.getBiome(carving.getRunning()); TerraBiome biome = provider.getBiome(carving.getRunning(), w.getSeed());
/* /*
if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(CarverCache.this.carver)) { // Stop if we enter a biome this carver is not present in if(!((UserDefinedBiome) biome).getConfig().getCarvers().containsKey(CarverCache.this.carver)) { // Stop if we enter a biome this carver is not present in
return Collections.emptyList(); return Collections.emptyList();

View File

@ -11,7 +11,7 @@ public class NoiseDistributor implements Distributor {
} }
@Override @Override
public boolean matches(int x, int z) { public boolean matches(int x, int z, long seed) {
return sampler.getNoise(x, z) > 0; return sampler.getNoiseSeeded(seed, x, z) > 0;
} }
} }

View File

@ -116,7 +116,7 @@ public class TerraFlora implements Flora {
for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor for(int i = 0; FastMath.abs(i) < size; i += c) { // Down if ceiling, up if floor
int lvl = (FastMath.abs(i)); int lvl = (FastMath.abs(i));
BlockState data = getStateCollection((ceiling ? lvl : size - lvl - 1)).get(distribution, location.getX(), location.getY(), location.getZ()).clone(); BlockState data = getStateCollection((ceiling ? lvl : size - lvl - 1)).get(distribution, location.getX(), location.getY(), location.getZ(), world.getSeed()).clone();
if(doRotation) { if(doRotation) {
Direction oneFace = new ArrayList<>(faces).get(new Random(location.getBlockX() ^ location.getBlockZ()).nextInt(faces.size())); // Get random face. Direction oneFace = new ArrayList<>(faces).get(new Random(location.getBlockX() ^ location.getBlockZ()).nextInt(faces.size())); // Get random face.

View File

@ -16,8 +16,6 @@ import com.dfsek.terra.addons.noise.config.templates.noise.fractal.RidgedFractal
import com.dfsek.terra.addons.noise.config.templates.normalizer.ClampNormalizerTemplate; import com.dfsek.terra.addons.noise.config.templates.normalizer.ClampNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearNormalizerTemplate; import com.dfsek.terra.addons.noise.config.templates.normalizer.LinearNormalizerTemplate;
import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizerTemplate; import com.dfsek.terra.addons.noise.config.templates.normalizer.NormalNormalizerTemplate;
import com.dfsek.terra.addons.noise.samplers.ImageSampler;
import com.dfsek.terra.addons.noise.samplers.noise.CellularSampler;
import com.dfsek.terra.addons.noise.samplers.noise.random.GaussianNoiseSampler; import com.dfsek.terra.addons.noise.samplers.noise.random.GaussianNoiseSampler;
import com.dfsek.terra.addons.noise.samplers.noise.random.WhiteNoiseSampler; import com.dfsek.terra.addons.noise.samplers.noise.random.WhiteNoiseSampler;
import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2SSampler; import com.dfsek.terra.addons.noise.samplers.noise.simplex.OpenSimplex2SSampler;
@ -64,10 +62,7 @@ public class NoiseAddon extends TerraAddon implements EventListener {
.applyLoader(DomainWarpTemplate.class, DomainWarpTemplate::new) .applyLoader(DomainWarpTemplate.class, DomainWarpTemplate::new)
.applyLoader(LinearNormalizerTemplate.class, LinearNormalizerTemplate::new) .applyLoader(LinearNormalizerTemplate.class, LinearNormalizerTemplate::new)
.applyLoader(NormalNormalizerTemplate.class, NormalNormalizerTemplate::new) .applyLoader(NormalNormalizerTemplate.class, NormalNormalizerTemplate::new)
.applyLoader(ImageSampler.Channel.class, (t, object, cf) -> ImageSampler.Channel.valueOf((String) object)) .applyLoader(ClampNormalizerTemplate.class, ClampNormalizerTemplate::new);
.applyLoader(ClampNormalizerTemplate.class, ClampNormalizerTemplate::new)
.applyLoader(CellularSampler.ReturnType.class, (t, object, cf) -> CellularSampler.ReturnType.valueOf((String) object))
.applyLoader(CellularSampler.DistanceFunction.class, (t, object, cf) -> CellularSampler.DistanceFunction.valueOf((String) object));
noiseRegistry.register("LINEAR", LinearNormalizerTemplate::new); noiseRegistry.register("LINEAR", LinearNormalizerTemplate::new);
noiseRegistry.register("NORMAL", NormalNormalizerTemplate::new); noiseRegistry.register("NORMAL", NormalNormalizerTemplate::new);
@ -81,20 +76,20 @@ public class NoiseAddon extends TerraAddon implements EventListener {
noiseRegistry.register("PINGPONG", PingPongTemplate::new); noiseRegistry.register("PINGPONG", PingPongTemplate::new);
noiseRegistry.register("RIDGED", RidgedFractalTemplate::new); noiseRegistry.register("RIDGED", RidgedFractalTemplate::new);
noiseRegistry.register("OPENSIMPLEX2", () -> new SimpleNoiseTemplate(OpenSimplex2Sampler::new)); noiseRegistry.register("OPENSIMPLEX2", () -> new SimpleNoiseTemplate(seed3 -> new OpenSimplex2Sampler()));
noiseRegistry.register("OPENSIMPLEX2S", () -> new SimpleNoiseTemplate(OpenSimplex2SSampler::new)); noiseRegistry.register("OPENSIMPLEX2S", () -> new SimpleNoiseTemplate(seed3 -> new OpenSimplex2SSampler()));
noiseRegistry.register("PERLIN", () -> new SimpleNoiseTemplate(PerlinSampler::new)); noiseRegistry.register("PERLIN", () -> new SimpleNoiseTemplate(seed2 -> new PerlinSampler()));
noiseRegistry.register("SIMPLEX", () -> new SimpleNoiseTemplate(SimplexSampler::new)); noiseRegistry.register("SIMPLEX", () -> new SimpleNoiseTemplate(seed2 -> new SimplexSampler()));
noiseRegistry.register("GABOR", GaborNoiseTemplate::new); noiseRegistry.register("GABOR", GaborNoiseTemplate::new);
noiseRegistry.register("VALUE", () -> new SimpleNoiseTemplate(ValueSampler::new)); noiseRegistry.register("VALUE", () -> new SimpleNoiseTemplate(ValueSampler::new));
noiseRegistry.register("VALUECUBIC", () -> new SimpleNoiseTemplate(ValueCubicSampler::new)); noiseRegistry.register("VALUECUBIC", () -> new SimpleNoiseTemplate(seed1 -> new ValueCubicSampler()));
noiseRegistry.register("CELLULAR", CellularNoiseTemplate::new); noiseRegistry.register("CELLULAR", CellularNoiseTemplate::new);
noiseRegistry.register("WHITENOISE", () -> new SimpleNoiseTemplate(WhiteNoiseSampler::new)); noiseRegistry.register("WHITENOISE", () -> new SimpleNoiseTemplate(seed -> new WhiteNoiseSampler()));
noiseRegistry.register("GAUSSIAN", () -> new SimpleNoiseTemplate(GaussianNoiseSampler::new)); noiseRegistry.register("GAUSSIAN", () -> new SimpleNoiseTemplate(seed -> new GaussianNoiseSampler()));
noiseRegistry.register("CONSTANT", ConstantNoiseTemplate::new); noiseRegistry.register("CONSTANT", ConstantNoiseTemplate::new);

View File

@ -24,6 +24,6 @@ public class DomainWarpTemplate extends SamplerTemplate<DomainWarpedSampler> {
@Override @Override
public NoiseSampler build(long seed) { public NoiseSampler build(long seed) {
return new DomainWarpedSampler(function.build(seed), warp.build(seed), (int) (seed + salt), amplitude); return new DomainWarpedSampler(function.build(seed), warp.build(seed), amplitude);
} }
} }

View File

@ -27,7 +27,7 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
private SeededNoiseSampler lookup = new SeededNoiseSampler() { private SeededNoiseSampler lookup = new SeededNoiseSampler() {
@Override @Override
public NoiseSampler build(long seed) { public NoiseSampler build(long seed) {
return new OpenSimplex2Sampler((int) seed); return new OpenSimplex2Sampler();
} }
@Override @Override
@ -38,7 +38,7 @@ public class CellularNoiseTemplate extends NoiseTemplate<CellularSampler> {
@Override @Override
public NoiseSampler build(long seed) { public NoiseSampler build(long seed) {
CellularSampler sampler = new CellularSampler((int) seed + salt); CellularSampler sampler = new CellularSampler();
sampler.setNoiseLookup(lookup.build(seed)); sampler.setNoiseLookup(lookup.build(seed));
sampler.setFrequency(frequency); sampler.setFrequency(frequency);
sampler.setJitterModifier(cellularJitter); sampler.setJitterModifier(cellularJitter);

View File

@ -28,7 +28,7 @@ public class GaborNoiseTemplate extends NoiseTemplate<GaborNoiseSampler> {
@Override @Override
public NoiseSampler build(long seed) { public NoiseSampler build(long seed) {
GaborNoiseSampler gaborNoiseSampler = new GaborNoiseSampler((int) seed + salt); GaborNoiseSampler gaborNoiseSampler = new GaborNoiseSampler();
gaborNoiseSampler.setFrequency(frequency); gaborNoiseSampler.setFrequency(frequency);
gaborNoiseSampler.setRotation(rotation); gaborNoiseSampler.setRotation(rotation);
gaborNoiseSampler.setIsotropic(isotropic); gaborNoiseSampler.setIsotropic(isotropic);

View File

@ -12,22 +12,12 @@ public abstract class Normalizer implements NoiseSampler {
public abstract double normalize(double in); public abstract double normalize(double in);
@Override @Override
public double getNoise(double x, double y) { public double getNoiseSeeded(long seed, double x, double y) {
return normalize(sampler.getNoise(x, y));
}
@Override
public double getNoise(double x, double y, double z) {
return normalize(sampler.getNoise(x, y, z));
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return normalize(sampler.getNoiseSeeded(seed, x, y)); return normalize(sampler.getNoiseSeeded(seed, x, y));
} }
@Override @Override
public double getNoiseSeeded(int seed, double x, double y, double z) { public double getNoiseSeeded(long seed, double x, double y, double z) {
return normalize(sampler.getNoiseSeeded(seed, x, y, z)); return normalize(sampler.getNoiseSeeded(seed, x, y, z));
} }
} }

View File

@ -4,6 +4,7 @@ import com.dfsek.paralithic.Expression;
import com.dfsek.paralithic.eval.parser.Parser; import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Scope; import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException; import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.dynamic.Context;
import com.dfsek.paralithic.functions.dynamic.DynamicFunction; import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate; import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
@ -31,6 +32,11 @@ public class UserDefinedFunction implements DynamicFunction {
return expression.evaluate(args); return expression.evaluate(args);
} }
@Override
public double eval(Context context, double... args) {
return expression.evaluate(context, args);
}
@Override @Override
public boolean isStateless() { public boolean isStateless() {
return true; return true;

View File

@ -1,7 +0,0 @@
package com.dfsek.terra.addons.noise.paralithic.noise;
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
public interface NoiseFunction extends DynamicFunction {
}

View File

@ -1,12 +1,13 @@
package com.dfsek.terra.addons.noise.paralithic.noise; package com.dfsek.terra.addons.noise.paralithic.noise;
import com.dfsek.paralithic.functions.dynamic.Context;
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
import com.dfsek.terra.addons.noise.util.HashMapDoubleDouble; import com.dfsek.terra.addons.noise.util.HashMapDoubleDouble;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
public class NoiseFunction2 implements NoiseFunction { public class NoiseFunction2 implements DynamicFunction {
private final NoiseSampler gen; private final NoiseSampler gen;
private final Cache cache = new Cache();
public NoiseFunction2(NoiseSampler gen) { public NoiseFunction2(NoiseSampler gen) {
this.gen = gen; this.gen = gen;
@ -19,36 +20,16 @@ public class NoiseFunction2 implements NoiseFunction {
@Override @Override
public double eval(double... args) { public double eval(double... args) {
return cache.get(gen, args[0], args[1]); throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
}
@Override
public double eval(Context context, double... args) {
return gen.getNoiseSeeded(((SeedContext) context).getSeed(), args[0], args[1]);
} }
@Override @Override
public boolean isStateless() { public boolean isStateless() {
return true; return false;
}
private static class Cache extends HashMapDoubleDouble {
private static final long serialVersionUID = 8915092734723467010L;
private static final int cacheSize = 384;
public Cache() {
super(cacheSize);
}
public double get(NoiseSampler noise, double x, double z) {
double xx = x >= 0 ? x * 2 : x * -2 - 1;
double zz = z >= 0 ? z * 2 : z * -2 - 1;
double key = (xx >= zz) ? (xx * xx + xx + zz) : (zz * zz + xx);
double value = this.get(key);
if(this.size() > cacheSize) {
this.clear();
}
return (value == 4.9E-324D ? addAndReturn(noise.getNoise(x, z), key) : value);
}
private synchronized double addAndReturn(double value, double key) {
this.put(key, value);
return value;
}
} }
} }

View File

@ -1,8 +1,10 @@
package com.dfsek.terra.addons.noise.paralithic.noise; package com.dfsek.terra.addons.noise.paralithic.noise;
import com.dfsek.paralithic.functions.dynamic.Context;
import com.dfsek.paralithic.functions.dynamic.DynamicFunction;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
public class NoiseFunction3 implements NoiseFunction { public class NoiseFunction3 implements DynamicFunction {
private final NoiseSampler gen; private final NoiseSampler gen;
public NoiseFunction3(NoiseSampler gen) { public NoiseFunction3(NoiseSampler gen) {
@ -16,11 +18,16 @@ public class NoiseFunction3 implements NoiseFunction {
@Override @Override
public double eval(double... args) { public double eval(double... args) {
return gen.getNoise(args[0], args[1], args[2]); throw new UnsupportedOperationException("Cannot evaluate seeded function without seed context.");
}
@Override
public double eval(Context context, double... args) {
return gen.getNoiseSeeded(((SeedContext) context).getSeed(), args[0], args[1], args[2]);
} }
@Override @Override
public boolean isStateless() { public boolean isStateless() {
return true; return false;
} }
} }

View File

@ -0,0 +1,15 @@
package com.dfsek.terra.addons.noise.paralithic.noise;
import com.dfsek.paralithic.functions.dynamic.Context;
public class SeedContext implements Context {
private final long seed;
public SeedContext(long seed) {
this.seed = seed;
}
public long getSeed() {
return seed;
}
}

View File

@ -5,40 +5,28 @@ import com.dfsek.terra.api.noise.NoiseSampler;
public class DomainWarpedSampler implements NoiseSampler { public class DomainWarpedSampler implements NoiseSampler {
private final NoiseSampler function; private final NoiseSampler function;
private final NoiseSampler warp; private final NoiseSampler warp;
private final int seed;
private final double amplitude; private final double amplitude;
public DomainWarpedSampler(NoiseSampler function, NoiseSampler warp, int seed, double amplitude) { public DomainWarpedSampler(NoiseSampler function, NoiseSampler warp, double amplitude) {
this.function = function; this.function = function;
this.warp = warp; this.warp = warp;
this.seed = seed;
this.amplitude = amplitude; this.amplitude = amplitude;
} }
@Override @Override
public double getNoise(double x, double y) { public double getNoiseSeeded(long seed, double x, double y) {
return getNoiseSeeded(seed, x, y); return function.getNoiseSeeded(seed++,
} x + warp.getNoiseSeeded(seed++, x, y) * amplitude,
y + warp.getNoiseSeeded(seed, x, y) * amplitude
@Override
public double getNoise(double x, double y, double z) {
return getNoiseSeeded(seed, x, y, z);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return function.getNoise(
x + warp.getNoiseSeeded(seed, x, y) * amplitude,
y + warp.getNoiseSeeded(seed + 1, x, y) * amplitude
); );
} }
@Override @Override
public double getNoiseSeeded(int seed, double x, double y, double z) { public double getNoiseSeeded(long seed, double x, double y, double z) {
return function.getNoise( return function.getNoiseSeeded(seed++,
x + warp.getNoiseSeeded(seed, x, y, z) * amplitude, x + warp.getNoiseSeeded(seed++, x, y, z) * amplitude,
y + warp.getNoiseSeeded(seed + 1, x, y, z) * amplitude, y + warp.getNoiseSeeded(seed++, x, y, z) * amplitude,
z + warp.getNoiseSeeded(seed + 2, x, y, z) * amplitude z + warp.getNoiseSeeded(seed, x, y, z) * amplitude
); );
} }
} }

View File

@ -8,6 +8,7 @@ import com.dfsek.terra.addons.noise.config.templates.FunctionTemplate;
import com.dfsek.terra.addons.noise.paralithic.defined.UserDefinedFunction; import com.dfsek.terra.addons.noise.paralithic.defined.UserDefinedFunction;
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2; import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction2;
import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3; import com.dfsek.terra.addons.noise.paralithic.noise.NoiseFunction3;
import com.dfsek.terra.addons.noise.paralithic.noise.SeedContext;
import com.dfsek.terra.api.noise.NoiseSampler; import com.dfsek.terra.api.noise.NoiseSampler;
import com.dfsek.terra.api.util.seeded.SeededNoiseSampler; import com.dfsek.terra.api.util.seeded.SeededNoiseSampler;
@ -46,22 +47,12 @@ public class ExpressionSampler implements NoiseSampler {
} }
@Override @Override
public double getNoise(double x, double y) { public double getNoiseSeeded(long seed, double x, double y) {
return getNoise(x, 0, y); return getNoiseSeeded(seed, x, y);
} }
@Override @Override
public double getNoise(double x, double y, double z) { public double getNoiseSeeded(long seed, double x, double y, double z) {
return expression.evaluate(x, y, z); return expression.evaluate(new SeedContext(seed), x, y, z);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return getNoise(x, y);
}
@Override
public double getNoiseSeeded(int seed, double x, double y, double z) {
return getNoise(x, y, z);
} }
} }

View File

@ -18,23 +18,13 @@ public class ImageSampler implements NoiseSampler {
} }
@Override @Override
public double getNoise(double x, double y) { public double getNoiseSeeded(long seed, double x, double y) {
return ((channel.getChannel(image.getRGB(FastMath.floorMod(FastMath.floorToInt(x * frequency), image.getWidth()), FastMath.floorMod(FastMath.floorToInt(y * frequency), image.getHeight()))) / 255D) - 0.5) * 2; return ((channel.getChannel(image.getRGB(FastMath.floorMod(FastMath.floorToInt(x * frequency), image.getWidth()), FastMath.floorMod(FastMath.floorToInt(y * frequency), image.getHeight()))) / 255D) - 0.5) * 2;
} }
@Override @Override
public double getNoise(double x, double y, double z) { public double getNoiseSeeded(long seed, double x, double y, double z) {
return getNoise(x, y); return getNoiseSeeded(seed, x, y);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return getNoise(x, y);
}
@Override
public double getNoiseSeeded(int seed, double x, double y, double z) {
return getNoise(x, y, z);
} }
public enum Channel { public enum Channel {

View File

@ -13,24 +13,14 @@ public class KernelSampler implements NoiseSampler {
} }
@Override @Override
public double getNoise(double x, double y) { public double getNoiseSeeded(long seed, double x, double y) {
return getNoiseSeeded(0, x, y);
}
@Override
public double getNoise(double x, double y, double z) {
return getNoiseSeeded(0, x, y, z);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
x *= frequency; x *= frequency;
y *= frequency; y *= frequency;
double accumulator = 0; double accumulator = 0;
for(int kx = 0; kx < kernel.length; kx++) { for(int kx = 0; kx < kernel.length; kx++) {
for(int ky = 0; ky < kernel[kx].length; ky++) { for(int ky = 0; ky < kernel[kx].length; ky++) {
accumulator += in.getNoise(x + kx, y + ky) * kernel[kx][ky]; accumulator += in.getNoiseSeeded(seed, x + kx, y + ky) * kernel[kx][ky];
} }
} }
@ -38,7 +28,7 @@ public class KernelSampler implements NoiseSampler {
} }
@Override @Override
public double getNoiseSeeded(int seed, double x, double y, double z) { public double getNoiseSeeded(long seed, double x, double y, double z) {
x *= frequency; x *= frequency;
y *= frequency; y *= frequency;
z *= frequency; z *= frequency;
@ -46,7 +36,7 @@ public class KernelSampler implements NoiseSampler {
for(int kx = 0; kx < kernel.length; kx++) { for(int kx = 0; kx < kernel.length; kx++) {
for(int ky = 0; ky < kernel[kx].length; ky++) { for(int ky = 0; ky < kernel[kx].length; ky++) {
accumulator += in.getNoise(x + kx, y, z + ky) * kernel[kx][ky]; accumulator += in.getNoiseSeeded(seed, x + kx, y, z + ky) * kernel[kx][ky];
} }
} }

View File

@ -192,9 +192,8 @@ public class CellularSampler extends NoiseFunction {
private NoiseSampler noiseLookup; private NoiseSampler noiseLookup;
public CellularSampler(int seed) { public CellularSampler() {
super(seed); noiseLookup = new OpenSimplex2Sampler();
noiseLookup = new OpenSimplex2Sampler(seed);
} }
public void setDistanceFunction(DistanceFunction distanceFunction) { public void setDistanceFunction(DistanceFunction distanceFunction) {
@ -214,7 +213,8 @@ public class CellularSampler extends NoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int xr = fastRound(x); int xr = fastRound(x);
int yr = fastRound(y); int yr = fastRound(y);
@ -349,7 +349,7 @@ public class CellularSampler extends NoiseFunction {
case Distance2Div: case Distance2Div:
return distance0 / distance1 - 1; return distance0 / distance1 - 1;
case NoiseLookup: case NoiseLookup:
return noiseLookup.getNoise(center.getX(), center.getZ()); return noiseLookup.getNoiseSeeded(sl, center.getX(), center.getZ());
case Distance3: case Distance3:
return distance2 - 1; return distance2 - 1;
case Distance3Add: case Distance3Add:
@ -366,7 +366,8 @@ public class CellularSampler extends NoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int xr = fastRound(x); int xr = fastRound(x);
int yr = fastRound(y); int yr = fastRound(y);
int zr = fastRound(z); int zr = fastRound(z);
@ -523,7 +524,7 @@ public class CellularSampler extends NoiseFunction {
case Distance2Div: case Distance2Div:
return distance0 / distance1 - 1; return distance0 / distance1 - 1;
case NoiseLookup: case NoiseLookup:
return noiseLookup.getNoise(center.getX(), center.getY(), center.getZ()); return noiseLookup.getNoiseSeeded(sl, center.getX(), center.getY(), center.getZ());
case Distance3: case Distance3:
return distance2 - 1; return distance2 - 1;
case Distance3Add: case Distance3Add:

View File

@ -7,17 +7,16 @@ public class ConstantSampler extends NoiseFunction {
private final double constant; private final double constant;
public ConstantSampler(double constant) { public ConstantSampler(double constant) {
super(0);
this.constant = constant; this.constant = constant;
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long seed, double x, double y) {
return constant; return constant;
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long seed, double x, double y, double z) {
return constant; return constant;
} }
} }

View File

@ -5,6 +5,7 @@ import com.dfsek.paralithic.eval.parser.Parser;
import com.dfsek.paralithic.eval.parser.Scope; import com.dfsek.paralithic.eval.parser.Scope;
import com.dfsek.paralithic.eval.tokenizer.ParseException; import com.dfsek.paralithic.eval.tokenizer.ParseException;
import com.dfsek.paralithic.functions.Function; import com.dfsek.paralithic.functions.Function;
import com.dfsek.terra.addons.noise.paralithic.noise.SeedContext;
import java.util.Map; import java.util.Map;
@ -15,7 +16,6 @@ public class ExpressionFunction extends NoiseFunction {
private final Expression expression; private final Expression expression;
public ExpressionFunction(Map<String, Function> functions, String eq, Map<String, Double> vars) throws ParseException { public ExpressionFunction(Map<String, Function> functions, String eq, Map<String, Double> vars) throws ParseException {
super(0);
Parser p = new Parser(); Parser p = new Parser();
Scope scope = new Scope(); Scope scope = new Scope();
@ -32,12 +32,12 @@ public class ExpressionFunction extends NoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long seed, double x, double y) {
return expression.evaluate(x, 0, y); return expression.evaluate(new SeedContext(seed), x, 0, y);
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long seed, double x, double y, double z) {
return expression.evaluate(x, y, z); return expression.evaluate(new SeedContext(seed), x, y, z);
} }
} }

View File

@ -18,9 +18,8 @@ public class GaborNoiseSampler extends NoiseFunction {
private double g = FastMath.exp(-impulsesPerCell); private double g = FastMath.exp(-impulsesPerCell);
public GaborNoiseSampler(int seed) { public GaborNoiseSampler() {
super(seed); rand = new WhiteNoiseSampler();
rand = new WhiteNoiseSampler(seed);
} }
public void setIsotropic(boolean isotropic) { public void setIsotropic(boolean isotropic) {
@ -57,16 +56,16 @@ public class GaborNoiseSampler extends NoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double z) { public double getNoiseRaw(long seed, double x, double z) {
return gaborNoise(seed, x, z); return gaborNoise(seed, x, z);
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long seed, double x, double y, double z) {
return gaborNoise(seed, x, z); return gaborNoise(seed, x, z);
} }
private double gaborNoise(int seed, double x, double y) { private double gaborNoise(long seed, double x, double y) {
x /= kernelRadius; x /= kernelRadius;
y /= kernelRadius; y /= kernelRadius;
int xi = fastFloor(x); int xi = fastFloor(x);
@ -82,7 +81,7 @@ public class GaborNoiseSampler extends NoiseFunction {
return noise; return noise;
} }
private double calculateCell(int seed, int xi, int yi, double x, double y) { private double calculateCell(long seed, int xi, int yi, double x, double y) {
long mashedSeed = murmur64(31L * xi + yi) + seed; long mashedSeed = murmur64(31L * xi + yi) + seed;
double gaussianSource = (rand.getNoiseRaw(mashedSeed++) + 1) / 2; double gaussianSource = (rand.getNoiseRaw(mashedSeed++) + 1) / 2;

View File

@ -20,11 +20,6 @@ public abstract class NoiseFunction implements NoiseSampler {
} }
protected double frequency = 0.02d; protected double frequency = 0.02d;
protected int seed;
public NoiseFunction(int seed) {
this.seed = seed;
}
protected static int fastFloor(double f) { protected static int fastFloor(double f) {
return f >= 0 ? (int) f : (int) f - 1; return f >= 0 ? (int) f : (int) f - 1;
@ -114,11 +109,6 @@ public abstract class NoiseFunction implements NoiseSampler {
return sinLookup((int) ((a + Math.PI / 2) * precision + 0.5f)); return sinLookup((int) ((a + Math.PI / 2) * precision + 0.5f));
} }
public void setSeed(int seed) {
this.seed = seed;
}
public double getFrequency() { public double getFrequency() {
return frequency; return frequency;
} }
@ -128,26 +118,16 @@ public abstract class NoiseFunction implements NoiseSampler {
} }
@Override @Override
public double getNoise(double x, double y) { public double getNoiseSeeded(long seed, double x, double y) {
return getNoiseSeeded(seed, x, y);
}
@Override
public double getNoise(double x, double y, double z) {
return getNoiseSeeded(seed, x, y, z);
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return getNoiseRaw(seed, x * frequency, y * frequency); return getNoiseRaw(seed, x * frequency, y * frequency);
} }
@Override @Override
public double getNoiseSeeded(int seed, double x, double y, double z) { public double getNoiseSeeded(long seed, double x, double y, double z) {
return getNoiseRaw(seed, x * frequency, y * frequency, z * frequency); return getNoiseRaw(seed, x * frequency, y * frequency, z * frequency);
} }
public abstract double getNoiseRaw(int seed, double x, double y); public abstract double getNoiseRaw(long seed, double x, double y);
public abstract double getNoiseRaw(int seed, double x, double y, double z); public abstract double getNoiseRaw(long seed, double x, double y, double z);
} }

View File

@ -4,11 +4,11 @@ import com.dfsek.terra.api.noise.NoiseSampler;
public class BrownianMotionSampler extends FractalNoiseFunction { public class BrownianMotionSampler extends FractalNoiseFunction {
public BrownianMotionSampler(int seed, NoiseSampler input) { public BrownianMotionSampler(int seed, NoiseSampler input) {
super(seed, input); super(input);
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long seed, double x, double y) {
double sum = 0; double sum = 0;
double amp = fractalBounding; double amp = fractalBounding;
@ -26,7 +26,7 @@ public class BrownianMotionSampler extends FractalNoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long seed, double x, double y, double z) {
double sum = 0; double sum = 0;
double amp = fractalBounding; double amp = fractalBounding;

View File

@ -11,8 +11,7 @@ public abstract class FractalNoiseFunction extends NoiseFunction {
protected double lacunarity = 2.0d; protected double lacunarity = 2.0d;
protected double weightedStrength = 0.0d; protected double weightedStrength = 0.0d;
public FractalNoiseFunction(int seed, NoiseSampler input) { public FractalNoiseFunction(NoiseSampler input) {
super(seed);
this.input = input; this.input = input;
frequency = 1; frequency = 1;
} }

View File

@ -6,7 +6,7 @@ public class PingPongSampler extends FractalNoiseFunction {
private double pingPongStrength = 2.0; private double pingPongStrength = 2.0;
public PingPongSampler(int seed, NoiseSampler input) { public PingPongSampler(int seed, NoiseSampler input) {
super(seed, input); super(input);
} }
@ -20,7 +20,7 @@ public class PingPongSampler extends FractalNoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long seed, double x, double y) {
double sum = 0; double sum = 0;
double amp = fractalBounding; double amp = fractalBounding;
@ -38,7 +38,7 @@ public class PingPongSampler extends FractalNoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long seed, double x, double y, double z) {
double sum = 0; double sum = 0;
double amp = fractalBounding; double amp = fractalBounding;

View File

@ -5,11 +5,11 @@ import com.dfsek.terra.api.noise.NoiseSampler;
public class RidgedFractalSampler extends FractalNoiseFunction { public class RidgedFractalSampler extends FractalNoiseFunction {
public RidgedFractalSampler(int seed, NoiseSampler input) { public RidgedFractalSampler(int seed, NoiseSampler input) {
super(seed, input); super(input);
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long seed, double x, double y) {
double sum = 0; double sum = 0;
double amp = fractalBounding; double amp = fractalBounding;
@ -27,7 +27,7 @@ public class RidgedFractalSampler extends FractalNoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long seed, double x, double y, double z) {
double sum = 0; double sum = 0;
double amp = fractalBounding; double amp = fractalBounding;

View File

@ -8,13 +8,12 @@ import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
public class GaussianNoiseSampler extends NoiseFunction { public class GaussianNoiseSampler extends NoiseFunction {
private final WhiteNoiseSampler whiteNoiseSampler; // Back with a white noise sampler. private final WhiteNoiseSampler whiteNoiseSampler; // Back with a white noise sampler.
public GaussianNoiseSampler(int seed) { public GaussianNoiseSampler() {
super(seed); whiteNoiseSampler = new WhiteNoiseSampler();
whiteNoiseSampler = new WhiteNoiseSampler(seed);
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long seed, double x, double y) {
double v1, v2, s; double v1, v2, s;
do { do {
v1 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y); v1 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y);
@ -26,7 +25,7 @@ public class GaussianNoiseSampler extends NoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long seed, double x, double y, double z) {
double v1, v2, s; double v1, v2, s;
do { do {
v1 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y, z); v1 = whiteNoiseSampler.getNoiseSeeded(seed++, x, y, z);

View File

@ -8,8 +8,7 @@ import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
public class WhiteNoiseSampler extends NoiseFunction { public class WhiteNoiseSampler extends NoiseFunction {
private static final long POSITIVE_POW1 = 0b01111111111L << 52; // Bits that when applied to the exponent/sign section of a double, produce a positive number with a power of 1. private static final long POSITIVE_POW1 = 0b01111111111L << 52; // Bits that when applied to the exponent/sign section of a double, produce a positive number with a power of 1.
public WhiteNoiseSampler(int seed) { public WhiteNoiseSampler() {
super(seed);
} }
public double getNoiseRaw(long seed) { public double getNoiseRaw(long seed) {
@ -17,33 +16,33 @@ public class WhiteNoiseSampler extends NoiseFunction {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long seed, double x, double y) {
return (getNoiseUnmapped(seed, x, y) - 1.5) * 2; return (getNoiseUnmapped(seed, x, y) - 1.5) * 2;
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long seed, double x, double y, double z) {
return (getNoiseUnmapped(seed, x, y, z) - 1.5) * 2; return (getNoiseUnmapped(seed, x, y, z) - 1.5) * 2;
} }
public double getNoiseUnmapped(int seed, double x, double y, double z) { public double getNoiseUnmapped(long seed, double x, double y, double z) {
long base = ((randomBits(seed, x, y, z)) & 0x000fffffffffffffL) | POSITIVE_POW1; // Sign and exponent long base = ((randomBits(seed, x, y, z)) & 0x000fffffffffffffL) | POSITIVE_POW1; // Sign and exponent
return Double.longBitsToDouble(base); return Double.longBitsToDouble(base);
} }
public double getNoiseUnmapped(int seed, double x, double y) { public double getNoiseUnmapped(long seed, double x, double y) {
long base = (randomBits(seed, x, y) & 0x000fffffffffffffL) | POSITIVE_POW1; // Sign and exponent long base = (randomBits(seed, x, y) & 0x000fffffffffffffL) | POSITIVE_POW1; // Sign and exponent
return Double.longBitsToDouble(base); return Double.longBitsToDouble(base);
} }
public long randomBits(int seed, double x, double y, double z) { public long randomBits(long seed, double x, double y, double z) {
long hashX = Double.doubleToRawLongBits(x) ^ seed; long hashX = Double.doubleToRawLongBits(x) ^ seed;
long hashZ = Double.doubleToRawLongBits(y) ^ seed; long hashZ = Double.doubleToRawLongBits(y) ^ seed;
long hash = (((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed) + Double.doubleToRawLongBits(z); long hash = (((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed) + Double.doubleToRawLongBits(z);
return murmur64(hash); return murmur64(hash);
} }
public long randomBits(int seed, double x, double y) { public long randomBits(long seed, double x, double y) {
long hashX = Double.doubleToRawLongBits(x) ^ seed; long hashX = Double.doubleToRawLongBits(x) ^ seed;
long hashZ = Double.doubleToRawLongBits(y) ^ seed; long hashZ = Double.doubleToRawLongBits(y) ^ seed;
long hash = ((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed; long hash = ((hashX ^ (hashX >>> 32)) + ((hashZ ^ (hashZ >>> 32)) << 32)) ^ seed;

View File

@ -4,13 +4,10 @@ package com.dfsek.terra.addons.noise.samplers.noise.simplex;
* NoiseSampler implementation to provide OpenSimplex2 (Smooth Variant) noise. * NoiseSampler implementation to provide OpenSimplex2 (Smooth Variant) noise.
*/ */
public class OpenSimplex2SSampler extends SimplexStyleSampler { public class OpenSimplex2SSampler extends SimplexStyleSampler {
public OpenSimplex2SSampler(int seed) {
super(seed);
}
@Override @Override
@SuppressWarnings("NumericOverflow") @SuppressWarnings("NumericOverflow")
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
// 2D OpenSimplex2S case is a modified 2D simplex noise. // 2D OpenSimplex2S case is a modified 2D simplex noise.
final double SQRT3 = 1.7320508075688772935274463415059; final double SQRT3 = 1.7320508075688772935274463415059;
@ -117,7 +114,8 @@ public class OpenSimplex2SSampler extends SimplexStyleSampler {
@Override @Override
@SuppressWarnings("NumericOverflow") @SuppressWarnings("NumericOverflow")
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
// 3D OpenSimplex2S case uses two offset rotated cube grids. // 3D OpenSimplex2S case uses two offset rotated cube grids.
final double R3 = (2.0 / 3.0); final double R3 = (2.0 / 3.0);
double r = (x + y + z) * R3; // Rotation, not skew double r = (x + y + z) * R3; // Rotation, not skew

View File

@ -6,12 +6,9 @@ package com.dfsek.terra.addons.noise.samplers.noise.simplex;
public class OpenSimplex2Sampler extends SimplexStyleSampler { public class OpenSimplex2Sampler extends SimplexStyleSampler {
private static final double SQRT3 = 1.7320508075688772935274463415059; private static final double SQRT3 = 1.7320508075688772935274463415059;
public OpenSimplex2Sampler(int seed) {
super(seed);
}
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
// 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex. // 2D OpenSimplex2 case uses the same algorithm as ordinary Simplex.
final double G2 = (3 - SQRT3) / 6; final double G2 = (3 - SQRT3) / 6;
@ -71,7 +68,8 @@ public class OpenSimplex2Sampler extends SimplexStyleSampler {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
// 3D OpenSimplex2Sampler case uses two offset rotated cube grids. // 3D OpenSimplex2Sampler case uses two offset rotated cube grids.
final double R3 = (2.0 / 3.0); final double R3 = (2.0 / 3.0);
double r = (x + y + z) * R3; // Rotation, not skew double r = (x + y + z) * R3; // Rotation, not skew

View File

@ -4,12 +4,9 @@ package com.dfsek.terra.addons.noise.samplers.noise.simplex;
* NoiseSampler implementation to provide Perlin Noise. * NoiseSampler implementation to provide Perlin Noise.
*/ */
public class PerlinSampler extends SimplexStyleSampler { public class PerlinSampler extends SimplexStyleSampler {
public PerlinSampler(int seed) {
super(seed);
}
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x0 = fastFloor(x); int x0 = fastFloor(x);
int y0 = fastFloor(y); int y0 = fastFloor(y);
@ -33,7 +30,8 @@ public class PerlinSampler extends SimplexStyleSampler {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x0 = fastFloor(x); int x0 = fastFloor(x);
int y0 = fastFloor(y); int y0 = fastFloor(y);
int z0 = fastFloor(z); int z0 = fastFloor(z);

View File

@ -23,10 +23,6 @@ public class SimplexSampler extends SimplexStyleSampler {
private static final int Z_PRIME = 6971; private static final int Z_PRIME = 6971;
public SimplexSampler(int seed) {
super(seed);
}
private static double gradCoord3D(int seed, int x, int y, int z, double xd, double yd, double zd) { private static double gradCoord3D(int seed, int x, int y, int z, double xd, double yd, double zd) {
int hash = seed; int hash = seed;
hash ^= X_PRIME * x; hash ^= X_PRIME * x;
@ -55,7 +51,8 @@ public class SimplexSampler extends SimplexStyleSampler {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
double t = (x + y) * F2; double t = (x + y) * F2;
int i = fastFloor(x + t); int i = fastFloor(x + t);
int j = fastFloor(y + t); int j = fastFloor(y + t);
@ -111,7 +108,8 @@ public class SimplexSampler extends SimplexStyleSampler {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
double t = (x + y + z) * F3; double t = (x + y + z) * F3;
int i = fastFloor(x + t); int i = fastFloor(x + t);
int j = fastFloor(y + t); int j = fastFloor(y + t);

View File

@ -71,10 +71,6 @@ public abstract class SimplexStyleSampler extends NoiseFunction {
1, 1, 0, 0, 0, -1, 1, 0, -1, 1, 0, 0, 0, -1, -1, 0 1, 1, 0, 0, 0, -1, 1, 0, -1, 1, 0, 0, 0, -1, -1, 0
}; };
public SimplexStyleSampler(int seed) {
super(seed);
}
protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) { protected static double gradCoord(int seed, int xPrimed, int yPrimed, double xd, double yd) {
int hash = hash(seed, xPrimed, yPrimed); int hash = hash(seed, xPrimed, yPrimed);
hash ^= hash >> 15; hash ^= hash >> 15;

View File

@ -1,12 +1,9 @@
package com.dfsek.terra.addons.noise.samplers.noise.value; package com.dfsek.terra.addons.noise.samplers.noise.value;
public class ValueCubicSampler extends ValueStyleNoise { public class ValueCubicSampler extends ValueStyleNoise {
public ValueCubicSampler(int seed) {
super(seed);
}
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x1 = fastFloor(x); int x1 = fastFloor(x);
int y1 = fastFloor(y); int y1 = fastFloor(y);
@ -35,7 +32,8 @@ public class ValueCubicSampler extends ValueStyleNoise {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x1 = fastFloor(x); int x1 = fastFloor(x);
int y1 = fastFloor(y); int y1 = fastFloor(y);
int z1 = fastFloor(z); int z1 = fastFloor(z);

View File

@ -2,11 +2,12 @@ package com.dfsek.terra.addons.noise.samplers.noise.value;
public class ValueSampler extends ValueStyleNoise { public class ValueSampler extends ValueStyleNoise {
public ValueSampler(int seed) { public ValueSampler(int seed) {
super(seed); super();
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y) { public double getNoiseRaw(long sl, double x, double y) {
int seed = (int) sl;
int x0 = fastFloor(x); int x0 = fastFloor(x);
int y0 = fastFloor(y); int y0 = fastFloor(y);
@ -25,7 +26,8 @@ public class ValueSampler extends ValueStyleNoise {
} }
@Override @Override
public double getNoiseRaw(int seed, double x, double y, double z) { public double getNoiseRaw(long sl, double x, double y, double z) {
int seed = (int) sl;
int x0 = fastFloor(x); int x0 = fastFloor(x);
int y0 = fastFloor(y); int y0 = fastFloor(y);
int z0 = fastFloor(z); int z0 = fastFloor(z);

View File

@ -3,9 +3,6 @@ package com.dfsek.terra.addons.noise.samplers.noise.value;
import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction; import com.dfsek.terra.addons.noise.samplers.noise.NoiseFunction;
public abstract class ValueStyleNoise extends NoiseFunction { public abstract class ValueStyleNoise extends NoiseFunction {
public ValueStyleNoise(int seed) {
super(seed);
}
protected static double valCoord(int seed, int xPrimed, int yPrimed) { protected static double valCoord(int seed, int xPrimed, int yPrimed) {
int hash = hash(seed, xPrimed, yPrimed); int hash = hash(seed, xPrimed, yPrimed);

View File

@ -31,7 +31,7 @@ public class OrePopulator implements TerraGenerationStage {
Random random = new Random(PopulationUtil.getCarverChunkSeed(chunk.getX() + cx, chunk.getZ() + cz, world.getSeed())); Random random = new Random(PopulationUtil.getCarverChunkSeed(chunk.getX() + cx, chunk.getZ() + cz, world.getSeed()));
int originX = ((chunk.getX() + cx) << 4); int originX = ((chunk.getX() + cx) << 4);
int originZ = ((chunk.getZ() + cz) << 4); int originZ = ((chunk.getZ() + cz) << 4);
TerraBiome b = tw.getBiomeProvider().getBiome(originX + 8, originZ + 8); TerraBiome b = tw.getBiomeProvider().getBiome(originX + 8, originZ + 8, world.getSeed());
/* /*
BiomeTemplate config = ((UserDefinedBiome) b).getConfig(); BiomeTemplate config = ((UserDefinedBiome) b).getConfig();
int finalCx = cx; int finalCx = cx;

View File

@ -15,7 +15,7 @@ public class NoisePalette extends PaletteImpl {
} }
@Override @Override
public BlockState get(int layer, double x, double y, double z) { public BlockState get(int layer, double x, double y, double z, long seed) {
PaletteLayer paletteLayer; PaletteLayer paletteLayer;
if(layer > this.getSize()) paletteLayer = this.getLayers().get(this.getLayers().size() - 1); if(layer > this.getSize()) paletteLayer = this.getLayers().get(this.getLayers().size() - 1);
else { else {
@ -24,6 +24,6 @@ public class NoisePalette extends PaletteImpl {
else paletteLayer = pl.get(layer); else paletteLayer = pl.get(layer);
} }
NoiseSampler paletteSampler = paletteLayer.getSampler(); NoiseSampler paletteSampler = paletteLayer.getSampler();
return paletteLayer.get(paletteSampler == null ? sampler : paletteSampler, x, y, z, is2D); return paletteLayer.get(paletteSampler == null ? sampler : paletteSampler, x, y, z, is2D, seed);
} }
} }

View File

@ -13,7 +13,7 @@ import java.util.Random;
* A class representation of a "slice" of the world. * A class representation of a "slice" of the world.
* Used to get a section of blocks, based on the depth at which they are found. * Used to get a section of blocks, based on the depth at which they are found.
*/ */
public abstract class PaletteImpl implements com.dfsek.terra.api.world.generator.Palette { public abstract class PaletteImpl implements Palette {
private final List<PaletteLayer> pallet = new ArrayList<>(); private final List<PaletteLayer> pallet = new ArrayList<>();
/** /**
@ -96,9 +96,9 @@ public abstract class PaletteImpl implements com.dfsek.terra.api.world.generator
return m; return m;
} }
public BlockState get(NoiseSampler random, double x, double y, double z, boolean is2D) { public BlockState get(NoiseSampler random, double x, double y, double z, boolean is2D, long seed) {
if(col && is2D) return this.collection.get(random, x, z); if(col && is2D) return this.collection.get(random, x, z, seed);
else if(col) return this.collection.get(random, x, y, z); else if(col) return this.collection.get(random, x, y, z, seed);
return m; return m;
} }
@ -115,7 +115,7 @@ public abstract class PaletteImpl implements com.dfsek.terra.api.world.generator
} }
@Override @Override
public BlockState get(int layer, double x, double y, double z) { public BlockState get(int layer, double x, double y, double z, long seed) {
return item; return item;
} }
} }

View File

@ -39,7 +39,7 @@ public class StructurePopulator implements TerraGenerationStage, Chunkified {
for(ConfiguredStructure conf : config.getRegistry(TerraStructure.class).entries()) { for(ConfiguredStructure conf : config.getRegistry(TerraStructure.class).entries()) {
Vector3 spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed()); Vector3 spawn = conf.getSpawn().getNearestSpawn(cx + 8, cz + 8, world.getSeed());
if(!provider.getBiome(spawn).getContext().get(BiomeStructures.class).getStructures().contains(conf)) { if(!provider.getBiome(spawn, world.getSeed()).getContext().get(BiomeStructures.class).getStructures().contains(conf)) {
continue; continue;
} }
Random random = new Random(PopulationUtil.getCarverChunkSeed(FastMath.floorDiv(spawn.getBlockX(), 16), FastMath.floorDiv(spawn.getBlockZ(), 16), world.getSeed())); Random random = new Random(PopulationUtil.getCarverChunkSeed(FastMath.floorDiv(spawn.getBlockX(), 16), FastMath.floorDiv(spawn.getBlockZ(), 16), world.getSeed()));

View File

@ -25,13 +25,14 @@ public class FeatureGenerationStage implements TerraGenerationStage {
try(ProfileFrame ignore = main.getProfiler().profile("feature")) { try(ProfileFrame ignore = main.getProfiler().profile("feature")) {
int cx = chunk.getX() << 4; int cx = chunk.getX() << 4;
int cz = chunk.getZ() << 4; int cz = chunk.getZ() << 4;
long seed = world.getSeed();
for(int x = 0; x < 16; x++) { for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) { for(int z = 0; z < 16; z++) {
int tx = cx + x; int tx = cx + x;
int tz = cz + z; int tz = cz + z;
ColumnImpl column = new ColumnImpl(tx, tz, world); ColumnImpl column = new ColumnImpl(tx, tz, world);
terraWorld.getBiomeProvider().getBiome(tx, tz).getContext().get(BiomeFeatures.class).getFeatures().forEach(feature -> { terraWorld.getBiomeProvider().getBiome(tx, tz, seed).getContext().get(BiomeFeatures.class).getFeatures().forEach(feature -> {
if(feature.getDistributor().matches(tx, tz)) { if(feature.getDistributor().matches(tx, tz, seed)) {
feature.getLocator() feature.getLocator()
.getSuitableCoordinates(column) .getSuitableCoordinates(column)
.forEach(y -> .forEach(y ->

View File

@ -33,12 +33,13 @@ public class FloraGenerationStage implements TerraGenerationStage {
try(ProfileFrame ignore = main.getProfiler().profile("flora")) { try(ProfileFrame ignore = main.getProfiler().profile("flora")) {
if(tw.getConfig().disableFlora()) return; if(tw.getConfig().disableFlora()) return;
long seed = world.getSeed();
BiomeProvider provider = tw.getBiomeProvider(); BiomeProvider provider = tw.getBiomeProvider();
Map<Vector2, List<FloraLayer>> layers = new HashMap<>(); Map<Vector2, List<FloraLayer>> layers = new HashMap<>();
for(int x = 0; x < 16; x++) { for(int x = 0; x < 16; x++) {
for(int z = 0; z < 16; z++) { for(int z = 0; z < 16; z++) {
Vector2 l = new Vector2(x, z); Vector2 l = new Vector2(x, z);
layers.put(l, provider.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z).getContext().get(BiomeFlora.class).getLayers()); layers.put(l, provider.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, seed).getContext().get(BiomeFlora.class).getLayers());
} }
} }

View File

@ -39,7 +39,7 @@ public class FloraLayer {
public void place(Chunk chunk, Vector2 coords) { public void place(Chunk chunk, Vector2 coords) {
int cx = (chunk.getX() << 4); int cx = (chunk.getX() << 4);
int cz = (chunk.getZ() << 4); int cz = (chunk.getZ() << 4);
Flora item = layer.get(noise, cx + coords.getX(), cz + coords.getZ()); Flora item = layer.get(noise, cx + coords.getX(), cz + coords.getZ(), chunk.getWorld().getSeed());
item.getValidSpawnsAt(chunk, (int) coords.getX(), (int) coords.getZ(), level).forEach(block -> item.plant(block.add(cx, 0, cz), chunk.getWorld())); item.getValidSpawnsAt(chunk, (int) coords.getX(), (int) coords.getZ(), level).forEach(block -> item.plant(block.add(cx, 0, cz), chunk.getWorld()));
} }
} }

View File

@ -40,7 +40,7 @@ public class TreeLayer {
} }
public void place(Chunk chunk, Vector2 coords) { public void place(Chunk chunk, Vector2 coords) {
Tree item = layer.get(noise, coords.getX(), coords.getZ()); Tree item = layer.get(noise, coords.getX(), coords.getZ(), chunk.getWorld().getSeed());
BlockState current; BlockState current;
int cx = (chunk.getX()) << 4; int cx = (chunk.getX()) << 4;
int cz = (chunk.getZ()) << 4; int cz = (chunk.getZ()) << 4;

View File

@ -35,9 +35,10 @@ public class TreePopulator implements TerraGenerationStage {
BiomeProvider provider = tw.getBiomeProvider(); BiomeProvider provider = tw.getBiomeProvider();
Random random = PopulationUtil.getRandom(chunk); Random random = PopulationUtil.getRandom(chunk);
long seed = world.getSeed();
for(int x = 0; x < 16; x += 2) { for(int x = 0; x < 16; x += 2) {
for(int z = 0; z < 16; z += 2) { for(int z = 0; z < 16; z += 2) {
for(TreeLayer layer : provider.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z).getContext().get(BiomeTrees.class).getTrees()) { for(TreeLayer layer : provider.getBiome((chunk.getX() << 4) + x, (chunk.getZ() << 4) + z, seed).getContext().get(BiomeTrees.class).getTrees()) {
if(layer.getDensity() >= random.nextDouble() * 100) { if(layer.getDensity() >= random.nextDouble() * 100) {
layer.place(chunk, new Vector2(offset(random, x), offset(random, z))); layer.place(chunk, new Vector2(offset(random, x), offset(random, z)));
} }

View File

@ -40,7 +40,7 @@ public class BiomeFunction implements Function<String> {
BiomeProvider grid = main.getWorld(arguments.getWorld()).getBiomeProvider(); BiomeProvider grid = main.getWorld(arguments.getWorld()).getBiomeProvider();
return grid.getBiome(arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ())))).getID(); return grid.getBiome(arguments.getBuffer().getOrigin().clone().add(new Vector3(FastMath.roundToInt(xz.getX()), y.apply(implementationArguments, variableMap).intValue(), FastMath.roundToInt(xz.getZ()))), arguments.getWorld().getSeed()).getID();
} }

View File

@ -13,7 +13,7 @@ configureDependencies()
group = "com.dfsek.terra.common" group = "com.dfsek.terra.common"
dependencies { dependencies {
"shadedApi"("com.dfsek:Paralithic:0.3.2") "shadedApi"("com.dfsek:Paralithic:0.4.0")
"shadedApi"("com.dfsek.tectonic:common:2.1.1") "shadedApi"("com.dfsek.tectonic:common:2.1.1")
"shadedApi"("com.dfsek.tectonic:yaml:2.1.1") "shadedApi"("com.dfsek.tectonic:yaml:2.1.1")

View File

@ -8,50 +8,26 @@ public interface NoiseSampler {
static NoiseSampler zero() { static NoiseSampler zero() {
return new NoiseSampler() { return new NoiseSampler() {
@Override @Override
public double getNoise(double x, double y) { public double getNoiseSeeded(long seed, double x, double y) {
return 0; return 0;
} }
@Override @Override
public double getNoise(double x, double y, double z) { public double getNoiseSeeded(long seed, double x, double y, double z) {
return 0;
}
@Override
public double getNoiseSeeded(int seed, double x, double y) {
return 0;
}
@Override
public double getNoiseSeeded(int seed, double x, double y, double z) {
return 0; return 0;
} }
}; };
} }
/** default double getNoiseSeeded(Vector3 vector3, long seed) {
* 2D noise at given position using current settings return getNoiseSeeded(seed, vector3.getX(), vector3.getY(), vector3.getZ());
* <p>
* Noise output bounded between -1...1
*/
double getNoise(double x, double y);
/**
* 3D noise at given position using current settings
* <p>
* Noise output bounded between -1...1
*/
double getNoise(double x, double y, double z);
default double getNoise(Vector3 vector3) {
return getNoise(vector3.getX(), vector3.getY(), vector3.getZ());
} }
default double getNoise(Vector2 vector2) { default double getNoiseSeeded(Vector2 vector2, long seed) {
return getNoise(vector2.getX(), vector2.getZ()); return getNoiseSeeded(seed, vector2.getX(), vector2.getZ());
} }
double getNoiseSeeded(int seed, double x, double y); double getNoiseSeeded(long seed, double x, double y);
double getNoiseSeeded(int seed, double x, double y, double z); double getNoiseSeeded(long seed, double x, double y, double z);
} }

View File

@ -1,13 +1,13 @@
package com.dfsek.terra.api.structure.feature; package com.dfsek.terra.api.structure.feature;
public interface Distributor { public interface Distributor {
boolean matches(int x, int z); boolean matches(int x, int z, long seed);
default Distributor and(Distributor other) { default Distributor and(Distributor other) {
return (x, z) -> this.matches(x, z) && other.matches(x, z); return (x, z, seed) -> this.matches(x, z, seed) && other.matches(x, z, seed);
} }
default Distributor or(Distributor other) { default Distributor or(Distributor other) {
return (x, z) -> this.matches(x, z) || other.matches(x, z); return (x, z, seed) -> this.matches(x, z, seed) || other.matches(x, z, seed);
} }
} }

View File

@ -38,15 +38,15 @@ public class ProbabilityCollection<E> implements Collection<E> {
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public E get(NoiseSampler n, double x, double y, double z) { public E get(NoiseSampler n, double x, double y, double z, long seed) {
if(array.length == 0) return null; if(array.length == 0) return null;
return (E) array[MathUtil.normalizeIndex(n.getNoise(x, y, z), array.length)]; return (E) array[MathUtil.normalizeIndex(n.getNoiseSeeded(seed, x, y, z), array.length)];
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public E get(NoiseSampler n, double x, double z) { public E get(NoiseSampler n, double x, double z, long seed) {
if(array.length == 0) return null; if(array.length == 0) return null;
return (E) array[MathUtil.normalizeIndex(n.getNoise(x, z), array.length)]; return (E) array[MathUtil.normalizeIndex(n.getNoiseSeeded(seed, x, z), array.length)];
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -183,12 +183,12 @@ public class ProbabilityCollection<E> implements Collection<E> {
} }
@Override @Override
public T get(NoiseSampler n, double x, double y, double z) { public T get(NoiseSampler n, double x, double y, double z, long seed) {
return single; return single;
} }
@Override @Override
public T get(NoiseSampler n, double x, double z) { public T get(NoiseSampler n, double x, double z, long seed) {
return single; return single;
} }

View File

@ -5,18 +5,13 @@ import com.dfsek.terra.api.vector.Vector3;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
public interface BiomeProvider { public interface BiomeProvider {
TerraBiome getBiome(int x, int z); TerraBiome getBiome(int x, int z, long seed);
default TerraBiome getBiome(Vector2 vector2) { default TerraBiome getBiome(Vector2 vector2, long seed) {
return getBiome(vector2.getBlockX(), vector2.getBlockZ()); return getBiome(vector2.getBlockX(), vector2.getBlockZ(), seed);
} }
default TerraBiome getBiome(Vector3 vector3) { default TerraBiome getBiome(Vector3 vector3, long seed) {
return getBiome(vector3.getBlockX(), vector3.getBlockZ()); return getBiome(vector3.getBlockX(), vector3.getBlockZ(), seed);
}
@Deprecated
enum Type {
IMAGE, PIPELINE, SINGLE
} }
} }

View File

@ -3,7 +3,7 @@ package com.dfsek.terra.api.world.biome.generation.pipeline;
import com.dfsek.terra.api.world.biome.TerraBiome; import com.dfsek.terra.api.world.biome.TerraBiome;
public interface BiomeSource { public interface BiomeSource {
TerraBiome getBiome(double x, double z); TerraBiome getBiome(double x, double z, long seed);
enum Type { enum Type {
NOISE NOISE

View File

@ -15,7 +15,7 @@ public interface Palette {
* @param layer - The layer at which to fetch the material. * @param layer - The layer at which to fetch the material.
* @return BlockData - The material fetched. * @return BlockData - The material fetched.
*/ */
BlockState get(int layer, double x, double y, double z); BlockState get(int layer, double x, double y, double z, long seed);
int getSize(); int getSize();
} }

View File

@ -53,7 +53,7 @@ public class TerraBiomeSource extends BiomeSource {
@Override @Override
public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) { public Biome getBiomeForNoiseGen(int biomeX, int biomeY, int biomeZ) {
TerraBiome biome = grid.getBiome(biomeX << 2, biomeZ << 2); TerraBiome biome = grid.getBiome(biomeX << 2, biomeZ << 2, seed);
return biomeRegistry.get(new Identifier("terra", FabricUtil.createBiomeID(pack, biome.getID()))); return biomeRegistry.get(new Identifier("terra", FabricUtil.createBiomeID(pack, biome.getID())));
} }
} }