228 lines
8.4 KiB
Java
228 lines
8.4 KiB
Java
package net.minecraft.world.level.levelgen.synth;
|
|
|
|
import com.google.common.annotations.VisibleForTesting;
|
|
import com.google.common.collect.ImmutableList;
|
|
import com.mojang.datafixers.util.Pair;
|
|
import it.unimi.dsi.fastutil.doubles.DoubleArrayList;
|
|
import it.unimi.dsi.fastutil.doubles.DoubleList;
|
|
import it.unimi.dsi.fastutil.ints.IntBidirectionalIterator;
|
|
import it.unimi.dsi.fastutil.ints.IntRBTreeSet;
|
|
import it.unimi.dsi.fastutil.ints.IntSortedSet;
|
|
import java.util.Arrays;
|
|
import java.util.List;
|
|
import java.util.Locale;
|
|
import java.util.Objects;
|
|
import java.util.stream.IntStream;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.util.Mth;
|
|
import net.minecraft.util.RandomSource;
|
|
import net.minecraft.world.level.levelgen.PositionalRandomFactory;
|
|
|
|
public class PerlinNoise {
|
|
private static final int ROUND_OFF = 33554432;
|
|
private final ImprovedNoise[] noiseLevels;
|
|
private final int firstOctave;
|
|
private final DoubleList amplitudes;
|
|
private final double lowestFreqValueFactor;
|
|
private final double lowestFreqInputFactor;
|
|
private final double maxValue;
|
|
|
|
@Deprecated
|
|
public static PerlinNoise createLegacyForBlendedNoise(RandomSource p_230533_, IntStream p_230534_) {
|
|
return new PerlinNoise(p_230533_, makeAmplitudes(new IntRBTreeSet(p_230534_.boxed().collect(ImmutableList.toImmutableList()))), false);
|
|
}
|
|
|
|
@Deprecated
|
|
public static PerlinNoise createLegacyForLegacyNetherBiome(RandomSource p_230526_, int p_230527_, DoubleList p_230528_) {
|
|
return new PerlinNoise(p_230526_, Pair.of(p_230527_, p_230528_), false);
|
|
}
|
|
|
|
public static PerlinNoise create(RandomSource p_230540_, IntStream p_230541_) {
|
|
return create(p_230540_, p_230541_.boxed().collect(ImmutableList.toImmutableList()));
|
|
}
|
|
|
|
public static PerlinNoise create(RandomSource p_230530_, List<Integer> p_230531_) {
|
|
return new PerlinNoise(p_230530_, makeAmplitudes(new IntRBTreeSet(p_230531_)), true);
|
|
}
|
|
|
|
public static PerlinNoise create(RandomSource p_230521_, int p_230522_, double p_230523_, double... p_230524_) {
|
|
DoubleArrayList doublearraylist = new DoubleArrayList(p_230524_);
|
|
doublearraylist.add(0, p_230523_);
|
|
return new PerlinNoise(p_230521_, Pair.of(p_230522_, doublearraylist), true);
|
|
}
|
|
|
|
public static PerlinNoise create(RandomSource p_230536_, int p_230537_, DoubleList p_230538_) {
|
|
return new PerlinNoise(p_230536_, Pair.of(p_230537_, p_230538_), true);
|
|
}
|
|
|
|
private static Pair<Integer, DoubleList> makeAmplitudes(IntSortedSet p_75431_) {
|
|
if (p_75431_.isEmpty()) {
|
|
throw new IllegalArgumentException("Need some octaves!");
|
|
} else {
|
|
int i = -p_75431_.firstInt();
|
|
int j = p_75431_.lastInt();
|
|
int k = i + j + 1;
|
|
if (k < 1) {
|
|
throw new IllegalArgumentException("Total number of octaves needs to be >= 1");
|
|
} else {
|
|
DoubleList doublelist = new DoubleArrayList(new double[k]);
|
|
IntBidirectionalIterator intbidirectionaliterator = p_75431_.iterator();
|
|
|
|
while (intbidirectionaliterator.hasNext()) {
|
|
int l = intbidirectionaliterator.nextInt();
|
|
doublelist.set(l + i, 1.0);
|
|
}
|
|
|
|
return Pair.of(-i, doublelist);
|
|
}
|
|
}
|
|
}
|
|
|
|
protected PerlinNoise(RandomSource p_230515_, Pair<Integer, DoubleList> p_230516_, boolean p_230517_) {
|
|
this.firstOctave = p_230516_.getFirst();
|
|
this.amplitudes = p_230516_.getSecond();
|
|
int i = this.amplitudes.size();
|
|
int j = -this.firstOctave;
|
|
this.noiseLevels = new ImprovedNoise[i];
|
|
if (p_230517_) {
|
|
PositionalRandomFactory positionalrandomfactory = p_230515_.forkPositional();
|
|
|
|
for (int k = 0; k < i; k++) {
|
|
if (this.amplitudes.getDouble(k) != 0.0) {
|
|
int l = this.firstOctave + k;
|
|
this.noiseLevels[k] = new ImprovedNoise(positionalrandomfactory.fromHashOf("octave_" + l));
|
|
}
|
|
}
|
|
} else {
|
|
ImprovedNoise improvednoise = new ImprovedNoise(p_230515_);
|
|
if (j >= 0 && j < i) {
|
|
double d0 = this.amplitudes.getDouble(j);
|
|
if (d0 != 0.0) {
|
|
this.noiseLevels[j] = improvednoise;
|
|
}
|
|
}
|
|
|
|
for (int i1 = j - 1; i1 >= 0; i1--) {
|
|
if (i1 < i) {
|
|
double d1 = this.amplitudes.getDouble(i1);
|
|
if (d1 != 0.0) {
|
|
this.noiseLevels[i1] = new ImprovedNoise(p_230515_);
|
|
} else {
|
|
skipOctave(p_230515_);
|
|
}
|
|
} else {
|
|
skipOctave(p_230515_);
|
|
}
|
|
}
|
|
|
|
if (Arrays.stream(this.noiseLevels).filter(Objects::nonNull).count() != this.amplitudes.stream().filter(p_192897_ -> p_192897_ != 0.0).count()) {
|
|
throw new IllegalStateException("Failed to create correct number of noise levels for given non-zero amplitudes");
|
|
}
|
|
|
|
if (j < i - 1) {
|
|
throw new IllegalArgumentException("Positive octaves are temporarily disabled");
|
|
}
|
|
}
|
|
|
|
this.lowestFreqInputFactor = Math.pow(2.0, -j);
|
|
this.lowestFreqValueFactor = Math.pow(2.0, i - 1) / (Math.pow(2.0, i) - 1.0);
|
|
this.maxValue = this.edgeValue(2.0);
|
|
}
|
|
|
|
protected double maxValue() {
|
|
return this.maxValue;
|
|
}
|
|
|
|
private static void skipOctave(RandomSource p_230519_) {
|
|
p_230519_.consumeCount(262);
|
|
}
|
|
|
|
public double getValue(double p_75409_, double p_75410_, double p_75411_) {
|
|
return this.getValue(p_75409_, p_75410_, p_75411_, 0.0, 0.0, false);
|
|
}
|
|
|
|
@Deprecated
|
|
public double getValue(double p_75418_, double p_75419_, double p_75420_, double p_75421_, double p_75422_, boolean p_75423_) {
|
|
double d0 = 0.0;
|
|
double d1 = this.lowestFreqInputFactor;
|
|
double d2 = this.lowestFreqValueFactor;
|
|
|
|
for (int i = 0; i < this.noiseLevels.length; i++) {
|
|
ImprovedNoise improvednoise = this.noiseLevels[i];
|
|
if (improvednoise != null) {
|
|
double d3 = improvednoise.noise(
|
|
wrap(p_75418_ * d1),
|
|
p_75423_ ? -improvednoise.yo : wrap(p_75419_ * d1),
|
|
wrap(p_75420_ * d1),
|
|
p_75421_ * d1,
|
|
p_75422_ * d1
|
|
);
|
|
d0 += this.amplitudes.getDouble(i) * d3 * d2;
|
|
}
|
|
|
|
d1 *= 2.0;
|
|
d2 /= 2.0;
|
|
}
|
|
|
|
return d0;
|
|
}
|
|
|
|
public double maxBrokenValue(double p_210644_) {
|
|
return this.edgeValue(p_210644_ + 2.0);
|
|
}
|
|
|
|
private double edgeValue(double p_210650_) {
|
|
double d0 = 0.0;
|
|
double d1 = this.lowestFreqValueFactor;
|
|
|
|
for (int i = 0; i < this.noiseLevels.length; i++) {
|
|
ImprovedNoise improvednoise = this.noiseLevels[i];
|
|
if (improvednoise != null) {
|
|
d0 += this.amplitudes.getDouble(i) * p_210650_ * d1;
|
|
}
|
|
|
|
d1 /= 2.0;
|
|
}
|
|
|
|
return d0;
|
|
}
|
|
|
|
@Nullable
|
|
public ImprovedNoise getOctaveNoise(int p_75425_) {
|
|
return this.noiseLevels[this.noiseLevels.length - 1 - p_75425_];
|
|
}
|
|
|
|
public static double wrap(double p_75407_) {
|
|
return p_75407_ - Mth.lfloor(p_75407_ / 3.3554432E7 + 0.5) * 3.3554432E7;
|
|
}
|
|
|
|
protected int firstOctave() {
|
|
return this.firstOctave;
|
|
}
|
|
|
|
protected DoubleList amplitudes() {
|
|
return this.amplitudes;
|
|
}
|
|
|
|
@VisibleForTesting
|
|
public void parityConfigString(StringBuilder p_192891_) {
|
|
p_192891_.append("PerlinNoise{");
|
|
List<String> list = this.amplitudes.stream().map(p_192889_ -> String.format(Locale.ROOT, "%.2f", p_192889_)).toList();
|
|
p_192891_.append("first octave: ").append(this.firstOctave).append(", amplitudes: ").append(list).append(", noise levels: [");
|
|
|
|
for (int i = 0; i < this.noiseLevels.length; i++) {
|
|
p_192891_.append(i).append(": ");
|
|
ImprovedNoise improvednoise = this.noiseLevels[i];
|
|
if (improvednoise == null) {
|
|
p_192891_.append("null");
|
|
} else {
|
|
improvednoise.parityConfigString(p_192891_);
|
|
}
|
|
|
|
p_192891_.append(", ");
|
|
}
|
|
|
|
p_192891_.append("]");
|
|
p_192891_.append("}");
|
|
}
|
|
} |