From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: JellySquid Date: Fri, 23 Oct 2020 16:45:51 -0500 Subject: [PATCH] lithium NoiseChunkGeneratorMixin Additional Optimizations By YatopiaMC, Original code by SuperCoder79, licensed under LGPLv3 you can find the original code on https://github.com/jellysquid3/lithium-fabric/ (Yarn mappings) diff --git a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java index 321ebe8891defb46f3ad3dfea37c9bb6e2025ad7..fa60285c0c48147ad09b9197bfe577f504dd34bd 100644 --- a/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java +++ b/src/main/java/net/minecraft/server/ChunkGeneratorAbstract.java @@ -5,6 +5,8 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import it.unimi.dsi.fastutil.objects.ObjectList; import it.unimi.dsi.fastutil.objects.ObjectListIterator; +import org.apache.commons.math3.util.FastMath; // Yatopia Fast Math + import java.util.Iterator; import java.util.List; import java.util.Random; @@ -111,7 +113,15 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { return this.w == i && ((GeneratorSettingBase) this.h.get()).a(resourcekey); } + // Yatopia start + private static double sampleOctave(NoiseGeneratorPerlin sampler, double x, double y, double z, double scaledVerticalSize, double scaledY, double frequency) { + return sampler.sample(x, y, z, scaledVerticalSize, scaledY) / frequency; + } + // Yatopia end + private double a(int i, int j, int k, double d0, double d1, double d2, double d3) { + // Yatopia start - replaced logic + /* double d4 = 0.0D; double d5 = 0.0D; double d6 = 0.0D; @@ -147,7 +157,85 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { } return MathHelper.b(d4 / 512.0D, d5 / 512.0D, (d6 / 10.0D + 1.0D) / 2.0D); + */ + double frequency = 1.0; + double interpolationValue = 0.0; + + // Calculate interpolation data to decide what noise to sample. + for (int octave = 0; octave < 8; octave++) { + double scaledVerticalScale = d3 * frequency; + double scaledY = j * scaledVerticalScale; + + interpolationValue += sampleOctave(this.s.a(octave), + NoiseGeneratorOctaves.a(i * d2 * frequency), + NoiseGeneratorOctaves.a(scaledY), + NoiseGeneratorOctaves.a(k * d2 * frequency), scaledVerticalScale, scaledY, frequency); + + frequency /= 2.0; + } + + double clampedInterpolation = (interpolationValue / 10.0 + 1.0) / 2.0; + + if (clampedInterpolation >= 1) { + // Sample only upper noise, as the lower noise will be interpolated out. + frequency = 1.0; + double noise = 0.0; + for (int octave = 0; octave < 16; octave++) { + double scaledVerticalScale = d1 * frequency; + double scaledY = j * scaledVerticalScale; + + noise += sampleOctave(this.r.a(octave), + NoiseGeneratorOctaves.a(i * d0 * frequency), + NoiseGeneratorOctaves.a(scaledY), + NoiseGeneratorOctaves.a(k * d0 * frequency), scaledVerticalScale, scaledY, frequency); + + frequency /= 2.0; + } + + return noise / 512.0; + } else if (clampedInterpolation <= 0) { + // Sample only lower noise, as the upper noise will be interpolated out. + frequency = 1.0; + double noise = 0.0; + for (int octave = 0; octave < 16; octave++) { + double scaledVerticalScale = d1 * frequency; + double scaledY = j * scaledVerticalScale; + noise += sampleOctave(this.q.a(octave), + NoiseGeneratorOctaves.a(i * d0 * frequency), + NoiseGeneratorOctaves.a(scaledY), + NoiseGeneratorOctaves.a(k * d0 * frequency), scaledVerticalScale, scaledY, frequency); + + frequency /= 2.0; + } + + return noise / 512.0; + } else { + // [VanillaCopy] SurfaceChunkGenerator#sampleNoise + // Sample both and interpolate, as in vanilla. + + frequency = 1.0; + double lowerNoise = 0.0; + double upperNoise = 0.0; + + for (int octave = 0; octave < 16; octave++) { + // Pre calculate these values to share them + double scaledVerticalScale = d1 * frequency; + double scaledY = j * scaledVerticalScale; + double xVal = NoiseGeneratorOctaves.a(i * d0 * frequency); + double yVal = NoiseGeneratorOctaves.a(scaledY); + double zVal = NoiseGeneratorOctaves.a(k * d0 * frequency); + + upperNoise += sampleOctave(this.r.a(octave), xVal, yVal, zVal, scaledVerticalScale, scaledY, frequency); + lowerNoise += sampleOctave(this.q.a(octave), xVal, yVal, zVal, scaledVerticalScale, scaledY, frequency); + + frequency /= 2.0; + } + + // Vanilla behavior, return interpolated noise + return MathHelper.d(clampedInterpolation, lowerNoise / 512.0, upperNoise / 512.0); + } } + // Yatopia end private double[] b(int i, int j) { double[] adouble = new double[this.o + 1]; @@ -273,7 +361,7 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { double d2 = d1 * 24.575625D - 2.0D; - return d2 < 0.0D ? d2 * 0.009486607142857142D : Math.min(d2, 1.0D) * 0.006640625D; + return d2 < 0.0D ? d2 * 0.009486607142857142D : FastMath.min(d2, 1.0D) * 0.006640625D; // Yatopia Fast Math } @Override @@ -290,10 +378,10 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { } private int a(int i, int j, @Nullable IBlockData[] aiblockdata, @Nullable Predicate predicate) { - int k = Math.floorDiv(i, this.m); - int l = Math.floorDiv(j, this.m); - int i1 = Math.floorMod(i, this.m); - int j1 = Math.floorMod(j, this.m); + int k = FastMath.floorDiv(i, this.m); // Yatopia Fast Math + int l = FastMath.floorDiv(j, this.m); // Yatopia Fast Math + int i1 = FastMath.floorMod(i, this.m); // Yatopia Fast Math + int j1 = FastMath.floorMod(j, this.m); // Yatopia Fast Math double d0 = (double) i1 / (double) this.m; double d1 = (double) j1 / (double) this.m; double[][] adouble = new double[][]{this.b(k, l), this.b(k, l + 1), this.b(k + 1, l), this.b(k + 1, l + 1)}; @@ -532,9 +620,9 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { StructurePiece structurepiece = (StructurePiece) objectlistiterator.next(); StructureBoundingBox structureboundingbox = structurepiece.g(); - k4 = Math.max(0, Math.max(structureboundingbox.a - j3, j3 - structureboundingbox.d)); + k4 = FastMath.max(0, FastMath.max(structureboundingbox.a - j3, j3 - structureboundingbox.d)); // Yatopia Fast Math l4 = j2 - (structureboundingbox.b + (structurepiece instanceof WorldGenFeaturePillagerOutpostPoolPiece ? ((WorldGenFeaturePillagerOutpostPoolPiece) structurepiece).d() : 0)); - i5 = Math.max(0, Math.max(structureboundingbox.c - i4, i4 - structureboundingbox.f)); + i5 = FastMath.max(0, FastMath.max(structureboundingbox.c - i4, i4 - structureboundingbox.f)); // Yatopia Fast Math } objectlistiterator.back(objectlist.size()); @@ -589,7 +677,7 @@ public final class ChunkGeneratorAbstract extends ChunkGenerator { double d0 = (double) (i * i + k * k); double d1 = (double) j + 0.5D; double d2 = d1 * d1; - double d3 = Math.pow(2.718281828459045D, -(d2 / 16.0D + d0 / 16.0D)); + double d3 = FastMath.pow(2.718281828459045D, -(d2 / 16.0D + d0 / 16.0D)); // Yatopia Fast Math double d4 = -d1 * MathHelper.i(d2 / 2.0D + d0 / 2.0D) / 2.0D; return d4 * d3;